Skip to main content

kstone_client/
error.rs

1/// Error types for the KeystoneDB client
2use thiserror::Error;
3use tonic::Status;
4
5#[derive(Error, Debug)]
6pub enum ClientError {
7    #[error("Not found: {0}")]
8    NotFound(String),
9
10    #[error("Invalid argument: {0}")]
11    InvalidArgument(String),
12
13    #[error("Condition check failed: {0}")]
14    ConditionCheckFailed(String),
15
16    #[error("Connection error: {0}")]
17    ConnectionError(String),
18
19    #[error("Server unavailable: {0}")]
20    Unavailable(String),
21
22    #[error("Request timeout: {0}")]
23    Timeout(String),
24
25    #[error("Internal server error: {0}")]
26    InternalError(String),
27
28    #[error("Data corruption: {0}")]
29    DataCorruption(String),
30
31    #[error("Transaction aborted: {0}")]
32    TransactionAborted(String),
33
34    #[error("Already exists: {0}")]
35    AlreadyExists(String),
36
37    #[error("Resource exhausted: {0}")]
38    ResourceExhausted(String),
39
40    #[error("Unimplemented: {0}")]
41    Unimplemented(String),
42
43    #[error("Permission denied: {0}")]
44    PermissionDenied(String),
45
46    #[error("Unknown error: {0}")]
47    Unknown(String),
48}
49
50pub type Result<T> = std::result::Result<T, ClientError>;
51
52/// Convert gRPC Status to ClientError
53impl From<Status> for ClientError {
54    fn from(status: Status) -> Self {
55        let msg = status.message().to_string();
56
57        match status.code() {
58            tonic::Code::NotFound => ClientError::NotFound(msg),
59            tonic::Code::InvalidArgument => ClientError::InvalidArgument(msg),
60            tonic::Code::FailedPrecondition => ClientError::ConditionCheckFailed(msg),
61            tonic::Code::Unavailable => ClientError::Unavailable(msg),
62            tonic::Code::DeadlineExceeded => ClientError::Timeout(msg),
63            tonic::Code::Internal => ClientError::InternalError(msg),
64            tonic::Code::DataLoss => ClientError::DataCorruption(msg),
65            tonic::Code::Aborted => ClientError::TransactionAborted(msg),
66            tonic::Code::AlreadyExists => ClientError::AlreadyExists(msg),
67            tonic::Code::ResourceExhausted => ClientError::ResourceExhausted(msg),
68            tonic::Code::Unimplemented => ClientError::Unimplemented(msg),
69            tonic::Code::PermissionDenied => ClientError::PermissionDenied(msg),
70            _ => ClientError::Unknown(msg),
71        }
72    }
73}