Connection Error
Handle connection failures and error classification.
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 panics turns a routine outage into a cascading failure. Fail-fast connection checking lets you detect an unreachable KubeMQ server the moment you .build() the client, so your service can log the failure, alert, or fall back instead of hanging.
.check_connection(true) makes KubemqClient::builder().build() perform a synchronous connectivity check during construction and return Err(KubemqError) immediately if the server is unreachable, rather than deferring the error to the first operation. Matching on e.code() against the ErrorCode variants — Validation, Transient, Timeout, Authentication, and others — lets you branch precisely, and e.is_retryable() / e.suggestion() give you a programmatic retry decision plus human-readable guidance. Gotchas: without check_connection(true), build() succeeds unconditionally and the same unreachable server only fails later, on the first send_event or similar call; is_retryable() reflects the failure category, not your retry budget — retrying an unreachable server in a tight loop just multiplies the outage; matching ErrorCode exhaustively means adding a wildcard arm, since new variants can be added to the enum over time.
Prerequisites
- KubeMQ server running on
localhost:50000 - Rust SDK installed (
cargo add kubemq)
Code
use kubemq::prelude::*;
use kubemq::{ErrorCode, EventBuilder, KubemqError};
#[tokio::main]
async fn main() -> kubemq::Result<()> {
let result = KubemqClient::builder()
.host("localhost")
.port(59999)
.check_connection(true)
.build()
.await;
match result {
Ok(client) => {
println!("Connected (unexpected)");
client.close().await?;
}
Err(ref e) => {
println!("Connection failed (expected): {}", e);
println!(" Error code: {:?}", e.code());
println!(" Is retryable: {}", e.is_retryable());
println!(" Suggestion: {}", e.suggestion());
}
}
let client_result = KubemqClient::builder()
.host("localhost")
.port(50000)
.build()
.await;
if let Ok(client) = client_result {
let event = EventBuilder::new()
.channel("")
.body(b"test".to_vec())
.build();
match client.send_event(event).await {
Ok(()) => println!("Sent (unexpected for empty channel)"),
Err(KubemqError::Validation {
code,
message,
suggestion,
..
}) => {
println!("Validation error (expected):");
println!(" Code: {:?}", code);
println!(" Message: {}", message);
println!(" Suggestion: {}", suggestion);
}
Err(e) => println!("Other error: {}", e),
}
let event = EventBuilder::new()
.channel("")
.body(b"test".to_vec())
.build();
if let Err(e) = client.send_event(event).await {
match e.code() {
ErrorCode::Validation => println!("Got validation error"),
ErrorCode::Transient => println!("Got transient error"),
ErrorCode::Timeout => println!("Got timeout error"),
ErrorCode::Authentication => println!("Got auth error"),
_ => println!("Got other error: {:?}", e.code()),
}
}
client.close().await?;
}
Ok(())
}How It Works
KubemqErrorvariants can be matched by destructuring or by callinge.code().is_retryable()returnstruefor Transient, Timeout, and Throttling errors.suggestion()provides human-readable recovery guidance.- Review timeouts, channel names, and client IDs before running against shared environments.
- Run the program while the server from the prerequisites is available.
Related
Was this page helpful?