1use thiserror::Error;
2
3pub type Result<T> = std::result::Result<T, BatataError>;
5
6#[derive(Error, Debug)]
8pub enum BatataError {
9 #[error("Config not found: dataId={data_id}, group={group}, namespace={namespace}")]
11 ConfigNotFound {
12 data_id: String,
13 group: String,
14 namespace: String,
15 },
16
17 #[error("Service not found: service={service_name}, group={group_name}, namespace={namespace}")]
19 ServiceNotFound {
20 service_name: String,
21 group_name: String,
22 namespace: String,
23 },
24
25 #[error("Connection error: {message}")]
27 ConnectionError { message: String },
28
29 #[error("Server error: code={error_code}, message={message}")]
31 ServerError { error_code: i32, message: String },
32
33 #[error("Authentication error: {message}")]
35 AuthError { message: String },
36
37 #[error("Permission denied: {message}")]
39 PermissionDenied { message: String },
40
41 #[error("Request timeout after {timeout_ms}ms")]
43 Timeout { timeout_ms: u64 },
44
45 #[error("Serialization error: {0}")]
47 SerializationError(#[from] serde_json::Error),
48
49 #[error("gRPC transport error: {0}")]
51 TransportError(#[from] tonic::transport::Error),
52
53 #[error("gRPC status error: {0}")]
55 GrpcStatus(#[from] tonic::Status),
56
57 #[error("Invalid parameter: {0}")]
59 InvalidParameter(String),
60
61 #[error("Internal error: {0}")]
63 Internal(String),
64
65 #[error("No available server")]
67 NoAvailableServer,
68
69 #[error("Client not started")]
71 ClientNotStarted,
72
73 #[error("Client already started")]
75 ClientAlreadyStarted,
76}
77
78impl BatataError {
79 pub fn is_retryable(&self) -> bool {
81 matches!(
82 self,
83 BatataError::ConnectionError { .. }
84 | BatataError::Timeout { .. }
85 | BatataError::TransportError(_)
86 | BatataError::NoAvailableServer
87 )
88 }
89
90 pub fn server_error(error_code: i32, message: impl Into<String>) -> Self {
92 BatataError::ServerError {
93 error_code,
94 message: message.into(),
95 }
96 }
97
98 pub fn connection_error(message: impl Into<String>) -> Self {
100 BatataError::ConnectionError {
101 message: message.into(),
102 }
103 }
104}