Skip to main content

rust_errkit/
kind.rs

1use serde::Serialize;
2use std::fmt;
3
4#[derive(Debug, Clone, Serialize)]
5pub enum ErrorDomain {
6    Core,
7    Network,
8    Database,
9    IO,
10    Auth,
11    External,
12}
13
14#[derive(Debug, Clone, Serialize)]
15pub enum ErrorReason {
16    // Infrastructure
17    Timeout,
18    ConnectionFailed,
19    ServerOverload,
20
21    // Data Resource
22    NotFound,
23    AlreadyExists,
24    ResourceExhausted,
25
26    // Auth
27    Unauthorized,
28    Forbidden,
29    SessionExpired,
30    InvalidToken,
31
32    // Business
33    InvalidInput,
34    ConstraintViolation,
35    InconsistentState,
36    ProcessingFailed,
37
38    // Security
39    ChecksumMismatch,
40    DataCorruption,
41
42    // More
43    Unexpected,
44}
45
46#[derive(Debug, Clone, Serialize)]
47pub struct ErrorKind {
48    pub domain: ErrorDomain,
49    pub reason: ErrorReason,
50}
51
52impl ErrorKind {
53    pub fn message(&self) -> &'static str {
54        self.reason.message()
55    }
56
57    pub fn new(domain: ErrorDomain, reason: ErrorReason) -> Self {
58        Self { domain, reason }
59    }
60
61    pub fn core(reason: ErrorReason) -> Self {
62        Self::new(ErrorDomain::Core, reason)
63    }
64
65    pub fn network(reason: ErrorReason) -> Self {
66        Self::new(ErrorDomain::Network, reason)
67    }
68
69    pub fn auth(reason: ErrorReason) -> Self {
70        Self::new(ErrorDomain::Auth, reason)
71    }
72
73    pub fn db(reason: ErrorReason) -> Self {
74        Self::new(ErrorDomain::Database, reason)
75    }
76
77    pub fn io(reason: ErrorReason) -> Self {
78        Self::new(ErrorDomain::IO, reason)
79    }
80
81    pub fn unknown() -> Self {
82        Self::new(ErrorDomain::External, ErrorReason::Unexpected)
83    }
84}
85
86impl fmt::Display for ErrorKind {
87    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
88        write!(
89            f,
90            "[{:?}] {:?}: {}",
91            self.domain,
92            self.reason,
93            self.message()
94        )
95    }
96}
97
98impl std::error::Error for ErrorKind {}
99
100impl ErrorReason {
101    pub fn message(&self) -> &'static str {
102        match self {
103            Self::Timeout => "The operation took too long to respond. Please try again later.",
104            Self::ConnectionFailed => "Unable to establish a connection to the server or service.",
105            Self::ServerOverload => "Server is currently under heavy load. Scaling in progress...",
106
107            Self::Unauthorized => "Authentication is required to access this resource.",
108            Self::Forbidden => "You do not have the necessary permissions for this action.",
109            Self::SessionExpired => "Your session has timed out. Please log in again.",
110            Self::InvalidToken => "The provided security token is invalid or malformed.",
111
112            Self::NotFound => "The requested resource could not be found in our records.",
113            Self::AlreadyExists => {
114                "Resource conflict: An entry with this identifier already exists."
115            }
116            Self::ResourceExhausted => "Daily limit exceeded or system resources are depleted.",
117
118            Self::InvalidInput => "The provided data is invalid or does not meet the requirements.",
119            Self::ConstraintViolation => {
120                "Operation rejected: Business rule or constraint violation."
121            }
122            Self::InconsistentState => "Internal data mismatch detected. Please refresh and retry.",
123            Self::ProcessingFailed => {
124                "The request was valid but we encountered an error during execution."
125            }
126
127            Self::ChecksumMismatch => "Integrity check failed. Data may have been tampered with.",
128            Self::DataCorruption => "Internal data structures appear to be corrupted.",
129
130            Self::Unexpected => {
131                "An unhandled exception occurred. Our engineers have been notified."
132            }
133        }
134    }
135}