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#

VariantWhen it occursWhat to do
NameNotFound(String)Agent name not registered on relayCheck the agent is running and connected
DeliveryFailed(String)Transport rejected the messageCheck peer connectivity, retry
TimeoutRPC exceeded 30s deadlineCheck handler performance, increase timeout logic
ConnectionFailed(String)Cannot connect to relay or peerCheck network, relay status
Internal(anyhow::Error)Unexpected internal errorFile a bug
Codec(prost::DecodeError)Protobuf encode/decode failureCheck message format
KeyError(String)Keypair load/generate failureCheck 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:

FailureRecovery
Name renewal failsRetries every 30s; after 5 failures triggers reconnect
Relay disconnectsWatchdog detects, reconnects with exponential backoff
All reconnects failLogs error after 10 attempts, stops retrying

Your application only needs to handle errors from explicit API calls (send, call, resolve). Background recovery is transparent.