1use thiserror::Error;
2
3#[derive(Error, Debug)]
5pub enum OatsError {
6 #[error("Object not found: {id}")]
7 ObjectNotFound { id: String },
8
9 #[error("Trait not found: {trait_name}")]
10 TraitNotFound { trait_name: String },
11
12 #[error("Action failed: {message}")]
13 ActionFailed { message: String },
14
15 #[error("System error: {message}")]
16 SystemError { message: String },
17
18 #[error("Invalid state: {message}")]
19 InvalidState { message: String },
20
21 #[error("Validation error: {message}")]
22 ValidationError { message: String },
23
24 #[error("Resource exhausted: {message}")]
25 ResourceExhausted { message: String },
26
27 #[error("Timeout error: {message}")]
28 TimeoutError { message: String },
29
30 #[error("Serialization error: {0}")]
31 SerializationError(#[from] serde_json::Error),
32
33 #[error("IO error: {0}")]
34 IoError(#[from] std::io::Error),
35
36 #[error("Unknown error: {message}")]
37 Unknown { message: String },
38}
39
40impl OatsError {
41 pub fn object_not_found(id: impl Into<String>) -> Self {
43 Self::ObjectNotFound { id: id.into() }
44 }
45
46 pub fn trait_not_found(trait_name: impl Into<String>) -> Self {
48 Self::TraitNotFound { trait_name: trait_name.into() }
49 }
50
51 pub fn action_failed(message: impl Into<String>) -> Self {
53 Self::ActionFailed { message: message.into() }
54 }
55
56 pub fn system_error(message: impl Into<String>) -> Self {
58 Self::SystemError { message: message.into() }
59 }
60
61 pub fn invalid_state(message: impl Into<String>) -> Self {
63 Self::InvalidState { message: message.into() }
64 }
65
66 pub fn unknown(message: impl Into<String>) -> Self {
68 Self::Unknown { message: message.into() }
69 }
70
71 pub fn validation_error(message: impl Into<String>) -> Self {
73 Self::ValidationError { message: message.into() }
74 }
75
76 pub fn resource_exhausted(message: impl Into<String>) -> Self {
78 Self::ResourceExhausted { message: message.into() }
79 }
80
81 pub fn timeout_error(message: impl Into<String>) -> Self {
83 Self::TimeoutError { message: message.into() }
84 }
85
86 pub fn is_recoverable(&self) -> bool {
88 matches!(self,
89 OatsError::ObjectNotFound { .. } |
90 OatsError::TraitNotFound { .. } |
91 OatsError::ValidationError { .. } |
92 OatsError::TimeoutError { .. }
93 )
94 }
95
96 pub fn is_fatal(&self) -> bool {
98 matches!(self,
99 OatsError::ResourceExhausted { .. } |
100 OatsError::InvalidState { .. } |
101 OatsError::SystemError { .. }
102 )
103 }
104}