1use thiserror::Error;
4
5#[derive(Debug, Error)]
7pub enum Error {
8 #[error("Queue connection failed: {0}")]
10 ConnectionFailed(String),
11
12 #[error("Failed to serialize job: {0}")]
14 SerializationFailed(String),
15
16 #[error("Failed to deserialize job: {0}")]
18 DeserializationFailed(String),
19
20 #[error("Failed to push job to queue '{queue}': {message}")]
22 PushFailed {
23 queue: String,
25 message: String,
27 },
28
29 #[error("Failed to pop job from queue '{queue}': {message}")]
31 PopFailed {
32 queue: String,
34 message: String,
36 },
37
38 #[error("Job '{job}' failed: {message}")]
40 JobFailed {
41 job: String,
43 message: String,
45 },
46
47 #[error("Job '{job}' exceeded maximum retries ({max_retries})")]
49 MaxRetriesExceeded {
50 job: String,
52 max_retries: u32,
54 },
55
56 #[error("Database error: {0}")]
58 Db(#[from] sea_orm::DbErr),
59
60 #[error("Unsupported database backend")]
62 UnsupportedBackend,
63
64 #[error("JSON error: {0}")]
66 Json(#[from] serde_json::Error),
67
68 #[error("Tenant not found for job: tenant_id={tenant_id}")]
70 TenantNotFound {
71 tenant_id: i64,
73 },
74
75 #[error("{0}")]
77 Custom(String),
78}
79
80impl Error {
81 pub fn job_failed(job: impl Into<String>, message: impl Into<String>) -> Self {
83 Self::JobFailed {
84 job: job.into(),
85 message: message.into(),
86 }
87 }
88
89 pub fn push_failed(queue: impl Into<String>, message: impl Into<String>) -> Self {
91 Self::PushFailed {
92 queue: queue.into(),
93 message: message.into(),
94 }
95 }
96
97 pub fn tenant_not_found(id: i64) -> Self {
99 Self::TenantNotFound { tenant_id: id }
100 }
101
102 pub fn custom(message: impl Into<String>) -> Self {
104 Self::Custom(message.into())
105 }
106}
107
108impl From<String> for Error {
109 fn from(s: String) -> Self {
110 Self::Custom(s)
111 }
112}
113
114impl From<&str> for Error {
115 fn from(s: &str) -> Self {
116 Self::Custom(s.to_string())
117 }
118}
119
120#[cfg(test)]
121mod tests {
122 use super::*;
123
124 #[test]
125 fn test_tenant_not_found_formats_with_id() {
126 let err = Error::tenant_not_found(42);
127 assert_eq!(err.to_string(), "Tenant not found for job: tenant_id=42");
128 }
129
130 #[test]
131 fn test_tenant_not_found_constructor() {
132 let err = Error::tenant_not_found(99);
133 assert!(matches!(err, Error::TenantNotFound { tenant_id: 99 }));
134 }
135}