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("Redis error: {0}")]
58 Redis(#[from] redis::RedisError),
59
60 #[error("JSON error: {0}")]
62 Json(#[from] serde_json::Error),
63
64 #[error("Tenant not found for job: tenant_id={tenant_id}")]
66 TenantNotFound {
67 tenant_id: i64,
69 },
70
71 #[error("{0}")]
73 Custom(String),
74}
75
76impl Error {
77 pub fn job_failed(job: impl Into<String>, message: impl Into<String>) -> Self {
79 Self::JobFailed {
80 job: job.into(),
81 message: message.into(),
82 }
83 }
84
85 pub fn push_failed(queue: impl Into<String>, message: impl Into<String>) -> Self {
87 Self::PushFailed {
88 queue: queue.into(),
89 message: message.into(),
90 }
91 }
92
93 pub fn tenant_not_found(id: i64) -> Self {
95 Self::TenantNotFound { tenant_id: id }
96 }
97
98 pub fn custom(message: impl Into<String>) -> Self {
100 Self::Custom(message.into())
101 }
102}
103
104impl From<String> for Error {
105 fn from(s: String) -> Self {
106 Self::Custom(s)
107 }
108}
109
110impl From<&str> for Error {
111 fn from(s: &str) -> Self {
112 Self::Custom(s.to_string())
113 }
114}
115
116#[cfg(test)]
117mod tests {
118 use super::*;
119
120 #[test]
121 fn test_tenant_not_found_formats_with_id() {
122 let err = Error::tenant_not_found(42);
123 assert_eq!(err.to_string(), "Tenant not found for job: tenant_id=42");
124 }
125
126 #[test]
127 fn test_tenant_not_found_constructor() {
128 let err = Error::tenant_not_found(99);
129 assert!(matches!(err, Error::TenantNotFound { tenant_id: 99 }));
130 }
131}