KubeMQ
Client SDKsJavaHow-to guidesError Handling

Connection Error

Detect and handle KubeMQ connection failures gracefully in the Java SDK with proper error reporting and recovery.

Overview

A network partition, a server that hasn't started yet, or a typo in the address are all normal facts of life in distributed systems — and a client that blocks indefinitely or crashes with an unhandled exception turns a routine outage into a cascading failure. Fail-fast connection checking lets you detect an unreachable KubeMQ server explicitly, rather than discovering it deep inside unrelated business logic, so your service can log the failure, alert, or fall back instead of hanging.

PubSubClient.builder().build() creates the gRPC channel eagerly but defers the TCP connection until the first RPC — calling ping() right after construction forces that connection and surfaces KubeMQException immediately if the server is unreachable. QueueSendResult.isError() and QueuesPollResponse.isError() catch a different failure class: application-level errors the broker returns over a successful transport, distinct from a thrown exception. Gotchas: build() succeeding tells you nothing about reachability — always ping() before relying on the connection; checking isError() is not optional, since a failed send or receive doesn't throw, it just returns a flagged result; unacknowledged messages from receiveQueueMessages are redelivered after the visibility timeout, so a crash between receive and ack() is expected, not a bug.

Prerequisites

  • KubeMQ server running on localhost:50000
  • Java SDK installed (implementation 'io.kubemq.sdk:kubemq-sdk-Java:3.1.1' (Gradle) or Maven dependency from Getting Started)

Code

ConnectionErrorExample.java
package io.kubemq.example.errorhandling;

import io.kubemq.sdk.common.ServerInfo;
import io.kubemq.sdk.pubsub.PubSubClient;
import io.kubemq.sdk.queues.*;

/**
 * Connection Error Example
 *
 * Demonstrates handling connection errors when working with KubeMQ.
 */
public class ConnectionErrorExample {

    private static final String ADDRESS = "localhost:50000";
    private static final String CLIENT_ID = "java-errorhandling-connection-error-client";

    public static void main(String[] args) {
        System.out.println("=== Connection Error Handling ===\n");

        // Test 1: Connection to invalid address (expect failure)
        System.out.println("1. Attempting connection to wrong address...");
        try {
            PubSubClient badClient = PubSubClient.builder()
                    .address("localhost:99999").clientId(CLIENT_ID).build();
            badClient.ping();
            badClient.close();
        } catch (Exception e) {
            System.out.println("   Failed (expected): " + e.getClass().getSimpleName());
        }

        // Test 2: Connection to valid address (expect success)
        System.out.println("\n2. Attempting connection to valid address...");
        try {
            PubSubClient goodClient = PubSubClient.builder()
                    .address(ADDRESS).clientId(CLIENT_ID).build();
            ServerInfo info = goodClient.ping();
            System.out.println("   Connected: " + info.getHost() + " v" + info.getVersion());
            goodClient.close();
        } catch (Exception e) {
            System.out.println("   Failed: " + e.getMessage());
        }

        // Test 3: Queue operations with error checking
        System.out.println("\n3. Queue operation error handling...");
        try (QueuesClient client = QueuesClient.builder().address(ADDRESS).clientId(CLIENT_ID).build()) {
            client.ping();
            String testQueue = "java-errorhandling.error-test";
            client.createQueuesChannel(testQueue);

            QueueSendResult result = client.sendQueueMessage(QueueMessage.builder()
                    .channel(testQueue).body("Test".getBytes()).build());
            System.out.println("   Send error: " + result.isError());

            QueuesPollResponse response = client.receiveQueueMessages(QueuesPollRequest.builder()
                    .channel(testQueue).pollMaxMessages(10).pollWaitTimeoutInSeconds(2).build());
            System.out.println("   Receive error: " + response.isError());
            response.getMessages().forEach(QueueMessageReceived::ack);

            client.deleteQueuesChannel(testQueue);
        } catch (Exception e) {
            System.out.println("   Error: " + e.getMessage());
        }

        System.out.println("\nConnection error examples completed.");
    }
}

How It Works

  • Connecting to an invalid address (localhost:99999) fails on the first RPC (ping()), not at build() — the gRPC channel is created eagerly but the actual TCP connection is deferred until first use.
  • KubeMQException (and its subclasses) are unchecked; wrap operations in try/catch at the level where you can meaningfully handle or log the failure.
  • QueueSendResult.isError() and QueuesPollResponse.isError() let you check application-level errors returned by the broker after a successful transport — these are separate from transport exceptions.
  • QueueMessageReceived::ack is called as a method reference to acknowledge each message individually; unacknowledged messages are redelivered after the visibility timeout.

Was this page helpful?

On this page