Errors
SubwayError types, causes, and how to handle them.
All fallible methods return SubwayResult<T> — Result<T, SubwayError>.
use subway_core::error::{SubwayError, SubwayResult};Error variants#
| Variant | When it occurs | What to do |
|---|---|---|
NameNotFound(String) | Agent name not registered on relay | Check the agent is running and connected |
DeliveryFailed(String) | Transport rejected the message | Check peer connectivity, retry |
Timeout | RPC exceeded 30s deadline | Check handler performance, increase timeout logic |
ConnectionFailed(String) | Cannot connect to relay or peer | Check network, relay status |
Internal(anyhow::Error) | Unexpected internal error | File a bug |
Codec(prost::DecodeError) | Protobuf encode/decode failure | Check message format |
KeyError(String) | Keypair load/generate failure | Check file permissions, disk space |
Pattern matching#
match node.call("target.relay", request).await {
Ok(response) => {
if response.success {
// handle response
} else {
eprintln!("RPC error: {}", response.error);
}
}
Err(SubwayError::NameNotFound(name)) => {
eprintln!("{} is not online", name);
}
Err(SubwayError::Timeout) => {
eprintln!("call timed out — handler too slow?");
}
Err(SubwayError::ConnectionFailed(reason)) => {
eprintln!("can't reach peer: {}", reason);
}
Err(e) => eprintln!("unexpected: {}", e),
}Automatic recovery#
Network errors are handled automatically by background tasks:
| Failure | Recovery |
|---|---|
| Name renewal fails | Retries every 30s; after 5 failures triggers reconnect |
| Relay disconnects | Watchdog detects, reconnects with exponential backoff |
| All reconnects fail | Logs error after 10 attempts, stops retrying |
Your application only needs to handle errors from explicit API calls (send, call, resolve). Background recovery is transparent.