//! Error types for the RPC layer. //! //! Provides a unified error type for client/server operations, //! with automatic conversions from underlying transport errors. use thiserror::Error; /// Errors that can occur during RPC operations. #[derive(Debug, Error)] pub enum RpcError { /// Connection failed or was refused. #[error("Connection error: {0}")] Connection(String), /// Request timed out. #[error("Request timeout: {0}")] Timeout(String), /// Server returned an error status. #[error("Server error: {0}")] Server(String), /// Failed to serialize/deserialize data. #[error("Serialization error: {0}")] Serialization(String), /// Invalid request or response data. #[error("Invalid data: {0}")] InvalidData(String), /// Maximum retry attempts exceeded. #[error("Retry limit exceeded after {attempts} attempts: {last_error}")] RetryExhausted { /// Number of attempts made. attempts: u32, /// The last error encountered. last_error: String, }, /// Internal transport error. #[error("Transport error: {0}")] Transport(String), } impl From for RpcError { fn from(status: tonic::Status) -> Self { match status.code() { tonic::Code::Unavailable | tonic::Code::Unknown => { RpcError::Connection(status.message().to_string()) } tonic::Code::DeadlineExceeded => RpcError::Timeout(status.message().to_string()), tonic::Code::InvalidArgument => RpcError::InvalidData(status.message().to_string()), _ => RpcError::Server(format!("{}: {}", status.code(), status.message())), } } } impl From for RpcError { fn from(err: tonic::transport::Error) -> Self { RpcError::Connection(err.to_string()) } } /// Result type for RPC operations. pub type Result = std::result::Result;