Skip to main content

fraiseql_error/
observer.rs

1/// Domain-level observer errors for `RuntimeError` aggregation.
2///
3/// These are the **client-facing** observer error variants. For operational
4/// observer errors with structured OB-codes (used in logging and retry
5/// decisions), see `fraiseql_observers::ObserverError`.
6#[derive(Debug, thiserror::Error)]
7#[non_exhaustive]
8pub enum ObserverError {
9    /// The observer's trigger condition expression could not be parsed or
10    /// evaluated.
11    #[error("Invalid condition: {message}")]
12    InvalidCondition {
13        /// Description of why the condition is invalid.
14        message: String,
15    },
16
17    /// An error occurred while rendering an observer action template (e.g.
18    /// an email body or webhook payload template).
19    #[error("Template error: {message}")]
20    TemplateError {
21        /// Description of the template rendering failure.
22        message: String,
23    },
24
25    /// The configured action (e.g. HTTP call, notification dispatch) failed
26    /// to execute.
27    #[error("Action failed: {action} - {message}")]
28    ActionFailed {
29        /// Name or type of the action that failed.
30        action:  String,
31        /// Reason for the failure.
32        message: String,
33    },
34
35    /// The observer definition contains an invalid or inconsistent
36    /// configuration value.
37    #[error("Invalid configuration: {message}")]
38    InvalidConfig {
39        /// Description of the configuration problem.
40        message: String,
41    },
42
43    /// The event payload could not be processed (e.g. deserialization failed
44    /// or required fields were missing).
45    #[error("Event processing failed: {message}")]
46    ProcessingFailed {
47        /// Description of the processing failure.
48        message: String,
49    },
50
51    /// The event has been retried the maximum number of times without
52    /// succeeding and is being moved to the dead-letter queue.
53    #[error("Max retries exceeded for event {event_id}")]
54    MaxRetriesExceeded {
55        /// Identifier of the event that exhausted its retry budget.
56        event_id: String,
57    },
58
59    /// A database error occurred while recording observer state or audit logs.
60    #[error("Database error: {0}")]
61    Database(#[from] sqlx::Error),
62}
63
64impl ObserverError {
65    /// Returns a short, stable error code string suitable for API responses and
66    /// structured logging.
67    pub const fn error_code(&self) -> &'static str {
68        match self {
69            Self::InvalidCondition { .. } => "observer_invalid_condition",
70            Self::TemplateError { .. } => "observer_template_error",
71            Self::ActionFailed { .. } => "observer_action_failed",
72            Self::InvalidConfig { .. } => "observer_invalid_config",
73            Self::ProcessingFailed { .. } => "observer_processing_failed",
74            Self::MaxRetriesExceeded { .. } => "observer_max_retries",
75            Self::Database(_) => "observer_database_error",
76        }
77    }
78}