use thiserror::Error;
pub type Result<T> = std::result::Result<T, SdkError>;
#[derive(Debug, Error)]
pub enum SdkError {
#[error("connection error: {0}")]
Connection(String),
#[error("transport error: {0}")]
Transport(#[from] tonic::transport::Error),
#[error("gRPC error: {0}")]
Grpc(#[from] tonic::Status),
#[error("operation timeout: {0}")]
Timeout(String),
#[error("configuration error: {0}")]
Configuration(String),
#[error("serialization error: {0}")]
Serialization(String),
#[error("FHE error: {0}")]
Fhe(String),
#[error("core error: {0}")]
Core(#[from] amaters_core::AmateRSError),
#[error("network error: {0}")]
Network(#[from] amaters_net::NetError),
#[error("invalid argument: {0}")]
InvalidArgument(String),
#[error("not found: {0}")]
NotFound(String),
#[error("operation failed: {0}")]
OperationFailed(String),
#[error("error: {0}")]
Other(String),
}
impl From<anyhow::Error> for SdkError {
fn from(err: anyhow::Error) -> Self {
Self::Other(err.to_string())
}
}
impl SdkError {
pub fn is_retryable(&self) -> bool {
matches!(
self,
Self::Connection(_) | Self::Transport(_) | Self::Timeout(_)
)
}
pub fn is_connection_error(&self) -> bool {
matches!(self, Self::Connection(_) | Self::Transport(_))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_error_is_retryable() {
let err = SdkError::Connection("test".to_string());
assert!(err.is_retryable());
let err = SdkError::InvalidArgument("test".to_string());
assert!(!err.is_retryable());
}
#[test]
fn test_error_display() {
let err = SdkError::Connection("failed to connect".to_string());
assert_eq!(err.to_string(), "connection error: failed to connect");
}
}