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}