1use std::fmt;
2
3#[derive(Debug)]
5pub enum Error {
6 Database(sqlx::Error),
7 Config(String),
8 Io(std::io::Error),
9 Json(serde_json::Error),
10 Other(String),
11 ParseError(String), InvalidRequest(String), MethodNotFound(String), InvalidParams(String), InternalError(String), Timeout(String), ValidationError(String), NotFound(String), Conflict(String), Unauthorized(String), RateLimited(String), }
25
26impl fmt::Display for Error {
27 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
28 match self {
29 Error::Database(e) => write!(f, "Database error: {}", e),
30 Error::Config(e) => write!(f, "Configuration error: {}", e),
31 Error::Io(e) => write!(f, "IO error: {}", e),
32 Error::Json(e) => write!(f, "JSON error: {}", e),
33 Error::Other(e) => write!(f, "Error: {}", e),
34 Error::ParseError(e) => write!(f, "Parse error: {}", e),
35 Error::InvalidRequest(e) => write!(f, "Invalid request: {}", e),
36 Error::MethodNotFound(e) => write!(f, "Method not found: {}", e),
37 Error::InvalidParams(e) => write!(f, "Invalid params: {}", e),
38 Error::InternalError(e) => write!(f, "Internal error: {}", e),
39 Error::Timeout(e) => write!(f, "Timeout: {}", e),
40 Error::ValidationError(e) => write!(f, "Validation error: {}", e),
41 Error::NotFound(e) => write!(f, "Not found: {}", e),
42 Error::Conflict(e) => write!(f, "Conflict: {}", e),
43 Error::Unauthorized(e) => write!(f, "Unauthorized: {}", e),
44 Error::RateLimited(e) => write!(f, "Rate limited: {}", e),
45 }
46 }
47}
48
49impl std::error::Error for Error {}
50
51impl From<sqlx::Error> for Error {
52 fn from(e: sqlx::Error) -> Self {
53 Error::Database(e)
54 }
55}
56
57impl From<std::io::Error> for Error {
58 fn from(e: std::io::Error) -> Self {
59 Error::Io(e)
60 }
61}
62
63impl From<serde_json::Error> for Error {
64 fn from(e: serde_json::Error) -> Self {
65 Error::Json(e)
66 }
67}
68
69impl From<anyhow::Error> for Error {
70 fn from(e: anyhow::Error) -> Self {
71 Error::Other(e.to_string())
72 }
73}
74
75impl From<url::ParseError> for Error {
76 fn from(e: url::ParseError) -> Self {
77 Error::Config(format!("Invalid URL: {}", e))
78 }
79}
80
81impl From<uuid::Error> for Error {
82 fn from(e: uuid::Error) -> Self {
83 Error::InvalidParams(format!("Invalid UUID: {}", e))
84 }
85}
86
87impl From<regex::Error> for Error {
88 fn from(e: regex::Error) -> Self {
89 Error::InternalError(format!("Regex error: {}", e))
90 }
91}
92
93impl From<tokio::time::error::Elapsed> for Error {
94 fn from(_: tokio::time::error::Elapsed) -> Self {
95 Error::Timeout("Operation timed out".to_string())
96 }
97}
98
99impl Error {
100 pub fn json_rpc_code(&self) -> i32 {
102 match self {
103 Error::ParseError(_) => -32700, Error::InvalidRequest(_) => -32600, Error::MethodNotFound(_) => -32601, Error::InvalidParams(_) | Error::ValidationError(_) => -32602, Error::InternalError(_) | Error::Timeout(_) => -32603, Error::Database(_) => -32603, Error::Config(_) => -32603, Error::Io(_) => -32603, Error::Json(_) => -32700, Error::Other(_) => -32603, Error::NotFound(_) => -32001, Error::Conflict(_) => -32002, Error::Unauthorized(_) => -32003, Error::RateLimited(_) => -32004, }
118 }
119
120 pub fn to_json_rpc_error(&self, id: Option<serde_json::Value>) -> serde_json::Value {
122 serde_json::json!({
123 "jsonrpc": "2.0",
124 "id": id,
125 "error": {
126 "code": self.json_rpc_code(),
127 "message": self.to_string()
128 }
129 })
130 }
131}
132
133pub type Result<T> = std::result::Result<T, Error>;