Skip to main content

ave_core/
error.rs

1//! Core API error types.
2//!
3//! These errors are exposed to end users through the API and should provide
4//! clear, actionable error messages.
5
6use thiserror::Error;
7
8/// Core API errors that may be returned to users.
9#[derive(Debug, Clone, Error)]
10pub enum Error {
11    // ========================================
12    // System Initialization Errors
13    // ========================================
14    /// System initialization failed.
15    #[error("System initialization failed: {0}")]
16    SystemInit(String),
17
18    /// Failed to create a required actor.
19    #[error("Failed to initialize {actor}: {reason}")]
20    ActorCreation { actor: String, reason: String },
21
22    /// Required helper or resource not found.
23    #[error("Required resource '{name}' not found: {reason}")]
24    MissingResource { name: String, reason: String },
25
26    // ========================================
27    // Network Errors
28    // ========================================
29    /// Network operation failed.
30    #[error("Network error: {0}")]
31    Network(String),
32
33    /// Unable to retrieve network state.
34    #[error("Unable to retrieve network state: {0}")]
35    NetworkState(String),
36
37    // ========================================
38    // Request Handling Errors
39    // ========================================
40    /// Request could not be processed.
41    #[error("Request processing failed: {0}")]
42    RequestProcessing(String),
43
44    /// Request signature is invalid or verification failed.
45    #[error("Invalid request signature: {0}")]
46    InvalidSignature(String),
47
48    /// Node was unable to sign the request.
49    #[error("Failed to sign request: {0}")]
50    SigningFailed(String),
51
52    /// Request not found in tracking system.
53    #[error("Request '{0}' not found")]
54    RequestNotFound(String),
55
56    /// Request is in an invalid state for this operation.
57    #[error("Request is in invalid state: {0}")]
58    InvalidRequestState(String),
59
60    // ========================================
61    // Approval Errors
62    // ========================================
63    /// Invalid approval state transition.
64    #[error("Invalid approval state: cannot set approval to '{0}'")]
65    InvalidApprovalState(String),
66
67    /// Approval not found for subject.
68    #[error("No approval request found for subject '{0}'")]
69    ApprovalNotFound(String),
70
71    /// Failed to update approval state.
72    #[error("Failed to update approval state: {0}")]
73    ApprovalUpdateFailed(String),
74
75    // ========================================
76    // Subject & Governance Errors
77    // ========================================
78    /// Subject not found.
79    #[error("Subject '{0}' not found")]
80    SubjectNotFound(String),
81
82    /// Subject is not active.
83    #[error("Subject '{0}' is not active")]
84    SubjectNotActive(String),
85
86    /// Governance not found.
87    #[error("Governance '{0}' not found")]
88    GovernanceNotFound(String),
89
90    /// Governance still has trackers associated and cannot be deleted.
91    #[error("Governance '{governance_id}' still has trackers associated")]
92    GovernanceHasTrackers {
93        governance_id: String,
94        trackers: Vec<String>,
95    },
96
97    /// Invalid subject identifier.
98    #[error("Invalid subject identifier: {0}")]
99    InvalidSubjectId(String),
100
101    // ========================================
102    // Authorization Errors
103    // ========================================
104    /// Authorization failed.
105    #[error("Authorization failed: {0}")]
106    Unauthorized(String),
107
108    /// Insufficient permissions for operation.
109    #[error("Insufficient permissions: {0}")]
110    Forbidden(String),
111
112    /// Node is running in safe mode and mutating operations are disabled.
113    #[error("Safe mode: {0}")]
114    SafeMode(String),
115
116    /// Authentication subject operation failed.
117    #[error("Authentication operation failed: {0}")]
118    AuthOperation(String),
119
120    /// Witnesses not found for subject.
121    #[error("No witnesses found for subject '{0}'")]
122    WitnessesNotFound(String),
123
124    // ========================================
125    // Query Errors
126    // ========================================
127    /// Query execution failed.
128    #[error("Query failed: {0}")]
129    QueryFailed(String),
130
131    /// No events found matching criteria.
132    #[error("No events found for subject '{0}'")]
133    NoEventsFound(String),
134
135    /// Event not found at specified sequence number.
136    #[error("Event not found for subject '{subject}' at sequence number {sn}")]
137    EventNotFound { subject: String, sn: u64 },
138
139    /// Invalid query parameters.
140    #[error("Invalid query parameters: {0}")]
141    InvalidQueryParams(String),
142
143    /// Database query error.
144    #[error("Database error: {0}")]
145    DatabaseError(String),
146
147    // ========================================
148    // Validation Errors
149    // ========================================
150    /// Request validation failed.
151    #[error("Validation failed: {0}")]
152    ValidationFailed(String),
153
154    /// Invalid event request format.
155    #[error("Invalid event request: {0}")]
156    InvalidEventRequest(String),
157
158    /// Schema validation failed.
159    #[error("Schema validation failed: {0}")]
160    SchemaValidation(String),
161
162    // ========================================
163    // Actor Communication Errors
164    // ========================================
165    /// Actor communication failed.
166    #[error("Internal communication error: failed to communicate with {actor}")]
167    ActorCommunication { actor: String },
168
169    /// Received unexpected response from actor.
170    #[error(
171        "Unexpected response from {actor}: expected {expected}, got {received}"
172    )]
173    UnexpectedResponse {
174        actor: String,
175        expected: String,
176        received: String,
177    },
178
179    /// Actor returned an error.
180    #[error("Operation failed: {0}")]
181    ActorError(String),
182
183    // ========================================
184    // Transfer Errors
185    // ========================================
186    /// Subject transfer operation failed.
187    #[error("Transfer operation failed: {0}")]
188    TransferFailed(String),
189
190    /// No pending transfers found.
191    #[error("No pending transfers found")]
192    NoPendingTransfers,
193
194    // ========================================
195    // Distribution Errors
196    // ========================================
197    /// Manual distribution failed.
198    #[error("Manual distribution failed for subject '{0}'")]
199    DistributionFailed(String),
200
201    /// Update operation failed.
202    #[error("Update failed for subject '{0}': {1}")]
203    UpdateFailed(String, String),
204
205    // ========================================
206    // Generic/Fallback Errors
207    // ========================================
208    /// Internal server error (catch-all for unexpected errors).
209    #[error("Internal error: {0}")]
210    Internal(String),
211
212    /// Operation timed out.
213    #[error("Operation timed out: {0}")]
214    Timeout(String),
215
216    /// Feature not implemented.
217    #[error("Feature not implemented: {0}")]
218    NotImplemented(String),
219}
220
221// Conversions from subsystem errors
222impl From<crate::system::SystemError> for Error {
223    fn from(err: crate::system::SystemError) -> Self {
224        Self::SystemInit(err.to_string())
225    }
226}
227
228impl From<ave_actors::ActorError> for Error {
229    fn from(err: ave_actors::ActorError) -> Self {
230        match err {
231            ave_actors::ActorError::NotFound { path } => {
232                Self::MissingResource {
233                    name: path.to_string(),
234                    reason: "Actor not found".to_string(),
235                }
236            }
237            ave_actors::ActorError::Functional { description } => {
238                Self::ActorError(description)
239            }
240            ave_actors::ActorError::FunctionalCritical { description } => {
241                Self::Internal(description)
242            }
243            _ => Self::Internal(err.to_string()),
244        }
245    }
246}