Skip to main content

agent_queue/
error.rs

1use thiserror::Error;
2
3/// Errors that can occur in the queue system.
4#[derive(Error, Debug)]
5pub enum QueueError {
6    #[error("Database error: {0}")]
7    Database(#[from] rusqlite::Error),
8
9    #[error("Serialization error: {0}")]
10    Serialization(#[from] serde_json::Error),
11
12    #[error("Job execution failed: {0}")]
13    Execution(String),
14
15    #[error("Job not found: {0}")]
16    NotFound(String),
17
18    #[error("Invalid state transition for job '{job_id}': {from} → {to}")]
19    InvalidTransition {
20        job_id: String,
21        from: String,
22        to: String,
23    },
24
25    #[error("Queue is paused")]
26    Paused,
27
28    #[error("Job was cancelled")]
29    Cancelled,
30
31    #[error("{0}")]
32    Other(String),
33}
34
35impl QueueError {
36    /// Stable string discriminant for structured logging (PRIMITIVES_CONTRACT §2).
37    pub fn kind(&self) -> &'static str {
38        match self {
39            Self::Database(_) => "database",
40            Self::Serialization(_) => "serialization",
41            Self::Execution(_) => "execution",
42            Self::NotFound(_) => "not_found",
43            Self::InvalidTransition { .. } => "invalid_transition",
44            Self::Paused => "paused",
45            Self::Cancelled => "cancelled",
46            Self::Other(_) => "other",
47        }
48    }
49}
50
51impl From<anyhow::Error> for QueueError {
52    fn from(err: anyhow::Error) -> Self {
53        QueueError::Other(err.to_string())
54    }
55}
56
57impl<T> From<std::sync::PoisonError<T>> for QueueError {
58    fn from(err: std::sync::PoisonError<T>) -> Self {
59        QueueError::Other(err.to_string())
60    }
61}