Skip to main content

forge_core/
error.rs

1use std::time::Duration;
2
3use thiserror::Error;
4
5/// Core error type for Forge operations.
6///
7/// Each variant maps to an HTTP status code and error code for consistent client handling.
8#[derive(Error, Debug)]
9pub enum ForgeError {
10    /// Configuration file parsing or validation failed.
11    #[error("Configuration error: {0}")]
12    Config(String),
13
14    /// Database operation failed.
15    #[error("Database error: {0}")]
16    Database(String),
17
18    /// Function execution failed.
19    #[error("Function error: {0}")]
20    Function(String),
21
22    /// Job execution failed.
23    #[error("Job error: {0}")]
24    Job(String),
25
26    /// Job was cancelled before completion.
27    #[error("Job cancelled: {0}")]
28    JobCancelled(String),
29
30    /// Cluster coordination failed.
31    #[error("Cluster error: {0}")]
32    Cluster(String),
33
34    /// Failed to serialize data to JSON.
35    #[error("Serialization error: {0}")]
36    Serialization(String),
37
38    /// Failed to deserialize JSON input.
39    #[error("Deserialization error: {0}")]
40    Deserialization(String),
41
42    /// File system operation failed.
43    #[error("IO error: {0}")]
44    Io(#[from] std::io::Error),
45
46    /// SQL execution failed.
47    #[error("SQL error: {0}")]
48    Sql(#[from] sqlx::Error),
49
50    /// Invalid argument provided (400).
51    #[error("Invalid argument: {0}")]
52    InvalidArgument(String),
53
54    /// Requested resource not found (404).
55    #[error("Not found: {0}")]
56    NotFound(String),
57
58    /// Authentication required or failed (401).
59    #[error("Unauthorized: {0}")]
60    Unauthorized(String),
61
62    /// Permission denied (403).
63    #[error("Forbidden: {0}")]
64    Forbidden(String),
65
66    /// Input validation failed (400).
67    #[error("Validation error: {0}")]
68    Validation(String),
69
70    /// Operation timed out (504).
71    #[error("Timeout: {0}")]
72    Timeout(String),
73
74    /// Unexpected internal error (500).
75    #[error("Internal error: {0}")]
76    Internal(String),
77
78    /// Invalid state transition attempted.
79    #[error("Invalid state: {0}")]
80    InvalidState(String),
81
82    /// Internal signal for workflow suspension. Never returned to clients.
83    #[error("Workflow suspended")]
84    WorkflowSuspended,
85
86    /// Rate limit exceeded (429).
87    #[error("Rate limit exceeded: retry after {retry_after:?}")]
88    RateLimitExceeded {
89        /// How long to wait before retrying.
90        retry_after: Duration,
91        /// The configured request limit.
92        limit: u32,
93        /// Remaining requests (always 0 when exceeded).
94        remaining: u32,
95    },
96}
97
98impl From<serde_json::Error> for ForgeError {
99    fn from(e: serde_json::Error) -> Self {
100        ForgeError::Serialization(e.to_string())
101    }
102}
103
104/// Result type alias using ForgeError.
105pub type Result<T> = std::result::Result<T, ForgeError>;