ferroid_tonic_core/common/error.rs
1//! Error types for the ID generation service.
2//!
3//! This module defines the central `Error` enum, which captures all recoverable
4//! and reportable error cases within the ID generation system. It implements
5//! `From<Error>` for `tonic::Status` to enable seamless gRPC error propagation
6//! to clients with appropriate status codes and messages.
7//!
8//! ## Error Cases
9//! - `ChannelError`: An internal communication failure between tasks or
10//! workers.
11//! - `IdGeneration`: An error occurred during ID creation (via the `ferroid`
12//! generator).
13//! - `RequestCancelled`: The client canceled the request mid-flight.
14//! - `InvalidRequest`: The client request was malformed or exceeded bounds.
15//! - `ServiceShutdown`: A request arrived while the service was shutting down.
16
17use tonic::Status;
18
19pub type Result<T> = core::result::Result<T, Error>;
20
21/// Unified error type for the ID generation service.
22#[derive(Clone, thiserror::Error, Debug)]
23#[non_exhaustive]
24pub enum Error {
25 /// Internal channel send/receive failure (e.g., closed or full channel).
26 #[error("Channel error: {context}")]
27 ChannelError { context: String },
28
29 /// Underlying Snowflake ID generation failed. This is currently infallible,
30 /// but kept as a placeholder if the generator type yields an error.
31 #[error("ID error: {0:?}")]
32 IdGeneration(#[from] core::convert::Infallible),
33
34 /// The client aborted the request.
35 #[error("Request cancelled by client")]
36 RequestCancelled,
37
38 /// The client request was invalid or exceeded constraints.
39 #[error("Invalid request: {reason}")]
40 InvalidRequest { reason: String },
41
42 /// The service is in the process of shutting down.
43 #[error("Service is shutting down")]
44 ServiceShutdown,
45}
46
47impl From<Error> for Status {
48 fn from(err: Error) -> Self {
49 match err {
50 Error::ChannelError { context } => Self::internal(format!("Channel error: {context}")),
51 Error::IdGeneration(e) => Self::internal(format!("ID generation error: {e:?}")),
52 Error::RequestCancelled => Self::cancelled("Request was cancelled"),
53 Error::InvalidRequest { reason } => Self::invalid_argument(reason),
54 Error::ServiceShutdown => Self::unavailable("Service is shutting down"),
55 }
56 }
57}