1use thiserror::Error;
4
5#[derive(Error, Debug)]
7pub enum Error {
8 #[error("Configuration error: {0}")]
9 Config(String),
10
11 #[error("Module error in {module}: {message}")]
12 Module { module: String, message: String },
13
14 #[error("Signal error: {0}")]
15 Signal(String),
16
17 #[error("Database error: {0}")]
18 Database(String),
19
20 #[error("Redis error: {0}")]
21 Redis(#[from] redis::RedisError),
22
23 #[error("Serialization error: {0}")]
24 Serialization(#[from] serde_json::Error),
25
26 #[error("IO error: {0}")]
27 Io(#[from] std::io::Error),
28
29 #[error("Channel send error: {0}")]
30 ChannelSend(String),
31
32 #[error("Channel receive error")]
33 ChannelRecv,
34
35 #[error("Health check failed: {0}")]
36 HealthCheck(String),
37
38 #[error("Shutdown error: {0}")]
39 Shutdown(String),
40
41 #[error("Internal error: {0}")]
42 Internal(String),
43}
44
45impl Error {
46 pub fn module(module: impl Into<String>, message: impl Into<String>) -> Self {
48 Self::Module {
49 module: module.into(),
50 message: message.into(),
51 }
52 }
53}
54
55pub type Result<T> = std::result::Result<T, Error>;
57
58impl<T> From<tokio::sync::broadcast::error::SendError<T>> for Error {
59 fn from(err: tokio::sync::broadcast::error::SendError<T>) -> Self {
60 Self::ChannelSend(err.to_string())
61 }
62}
63
64impl From<tokio::sync::broadcast::error::RecvError> for Error {
65 fn from(_: tokio::sync::broadcast::error::RecvError) -> Self {
66 Self::ChannelRecv
67 }
68}
69
70impl From<anyhow::Error> for Error {
71 fn from(err: anyhow::Error) -> Self {
72 Self::Internal(err.to_string())
73 }
74}
75
76#[cfg(test)]
77mod tests {
78 use super::*;
79
80 #[test]
81 fn test_module_error() {
82 let err = Error::module("forward", "failed to start");
83 assert!(err.to_string().contains("forward"));
84 }
85}