Error Handling
The Slipstream SDK uses a unified error type across all three languages.
SdkError Variants
| Variant | Description | Retryable |
|---|---|---|
Config | Invalid configuration | No |
Connection | Network/connection error | Yes |
Auth | Invalid or expired API key | No |
Protocol | Protocol-level error | Yes |
Transaction | Transaction processing error | No |
Timeout | Request timed out | Yes |
AllProtocolsFailed | All protocols in fallback chain failed | Yes |
RateLimited | Too many requests | Yes |
NotConnected | Client not connected | Yes |
StreamClosed | Stream subscription closed | Yes |
InsufficientTokens | Not enough tokens | No |
Internal | Internal server error | Yes |
Error Handling — Rust
use allenhark_slipstream::SdkError;
match client.submit_transaction(&tx_bytes).await {
Ok(result) => println!("Success: {:?}", result.signature),
Err(SdkError::Auth(msg)) => {
eprintln!("Authentication error: {} — check your API key", msg);
}
Err(SdkError::InsufficientTokens) => {
eprintln!("Not enough tokens — deposit SOL to continue");
let deposit = client.get_deposit_address().await?;
eprintln!("Deposit to: {:?}", deposit);
}
Err(SdkError::RateLimited(msg)) => {
eprintln!("Rate limited: {}", msg);
// SDK retries automatically based on config
}
Err(SdkError::Timeout(duration)) => {
eprintln!("Timed out after {:?}", duration);
}
Err(SdkError::AllProtocolsFailed) => {
eprintln!("All protocols failed — check network connectivity");
}
Err(SdkError::Connection(msg)) => {
eprintln!("Connection error: {}", msg);
// SDK will auto-reconnect on next call
}
Err(SdkError::NotConnected) => {
eprintln!("Not connected — reconnecting...");
}
Err(SdkError::StreamClosed) => {
eprintln!("Stream closed — resubscribe");
}
Err(e) => eprintln!("Unexpected error: {}", e),
}Error Handling — TypeScript
import { SlipstreamClient } from "@allenhark/slipstream";
try {
const result = await client.submitTransaction(txBytes);
console.log("Success:", result.signature);
} catch (err: any) {
switch (err.code) {
case "AUTH":
console.error("Auth error — check your API key");
break;
case "INSUFFICIENT_TOKENS":
console.error("Not enough tokens");
const deposit = await client.getDepositAddress();
console.error("Deposit to:", deposit);
break;
case "RATE_LIMITED":
console.error("Rate limited:", err.message);
break;
case "TIMEOUT":
console.error("Request timed out");
break;
case "ALL_PROTOCOLS_FAILED":
console.error("All protocols failed");
break;
case "CONNECTION":
console.error("Connection error:", err.message);
break;
case "NOT_CONNECTED":
console.error("Not connected");
break;
default:
console.error("Unexpected error:", err);
}
}Error Handling — Python
from allenhark_slipstream import SdkError
try:
result = await client.submit_transaction(tx_bytes)
print(f"Success: {result.signature}")
except SdkError as e:
if e.is_auth():
print(f"Auth error — check your API key: {e}")
elif e.is_insufficient_tokens():
print("Not enough tokens — deposit SOL")
elif e.is_rate_limited():
print(f"Rate limited: {e}")
elif e.is_timeout():
print("Request timed out")
elif e.is_connection():
print(f"Connection error: {e}")
else:
print(f"Error: {e}")Retry Configuration
The SDK has built-in retry logic with configurable backoff.
Config-Level Retries — Rust
let config = Config::builder()
.api_key("sk_live_...")
.max_retries(3)
.retry_backoff(BackoffStrategy::Exponential)
.build()?;Per-Request Retries — Rust
let result = client.submit_transaction_with_options(&tx_bytes, &SubmitOptions {
max_retries: 5,
retry: Some(RetryOptions {
max_retries: 5,
backoff_base_ms: 100,
cross_sender_retry: true, // Try a different sender on retry
}),
..Default::default()
}).await?;Backoff Strategies
| Strategy | Description |
|---|---|
Linear | Wait = base_ms * attempt |
Exponential | Wait = base_ms * 2^attempt (default) |
Connection Events
Monitor connection state changes.
Events — Rust
println!("Connected: {}", client.is_connected());
let info = client.connection_info();
println!("Session: {}, Protocol: {:?}", info.session_id, info.protocol);Events — TypeScript
client.on("connected", () => console.log("Connected!"));
client.on("disconnected", () => console.log("Disconnected"));
client.on("error", (err) => console.error("Error:", err));
console.log("Connected:", client.isConnected());Events — Python
@client.on("connected")
async def on_connected():
print("Connected!")
@client.on("disconnected")
async def on_disconnected():
print("Disconnected")
@client.on("error")
async def on_error(err):
print(f"Error: {err}")Performance Metrics
Track success rates and latency.
Metrics — Rust
let metrics = client.metrics();
println!("Submitted: {}", metrics.transactions_submitted);
println!("Confirmed: {}", metrics.transactions_confirmed);
println!("Avg latency: {:.1}ms", metrics.average_latency_ms);
println!("Success rate: {:.1}%", metrics.success_rate * 100.0);Metrics — TypeScript
const metrics = client.metrics();
console.log(`Success rate: ${(metrics.successRate * 100).toFixed(1)}%`);
console.log(`Avg latency: ${metrics.averageLatencyMs.toFixed(1)}ms`);Next Steps
- Configuration — Timeout and retry settings
- Multi-Region — Region failover
- Webhooks — Error event notifications
