1use thiserror::Error;
4
5pub type Result<T> = std::result::Result<T, Error>;
7
8#[derive(Error, Debug)]
10pub enum Error {
11 #[error("HTTP request failed: {0}")]
13 Http(#[from] reqwest::Error),
14
15 #[error("JSON error: {0}")]
17 Json(#[from] serde_json::Error),
18
19 #[error("URL parse error: {0}")]
21 UrlParse(#[from] url::ParseError),
22
23 #[error("JWT error: {0}")]
25 Jwt(#[from] jsonwebtoken::errors::Error),
26
27 #[error("Authentication error: {message}")]
29 Auth { message: String },
30
31 #[error("Database error: {message}")]
33 Database { message: String },
34
35 #[error("Storage error: {message}")]
37 Storage { message: String },
38
39 #[error("Realtime error: {message}")]
41 Realtime { message: String },
42
43 #[error("Configuration error: {message}")]
45 Config { message: String },
46
47 #[error("Invalid input: {message}")]
49 InvalidInput { message: String },
50
51 #[error("Network error: {message}")]
53 Network { message: String },
54
55 #[error("Rate limit exceeded: {message}")]
57 RateLimit { message: String },
58
59 #[error("Permission denied: {message}")]
61 PermissionDenied { message: String },
62
63 #[error("Not found: {message}")]
65 NotFound { message: String },
66
67 #[error("{message}")]
69 Generic { message: String },
70}
71
72impl Error {
73 pub fn auth<S: Into<String>>(message: S) -> Self {
75 Self::Auth {
76 message: message.into(),
77 }
78 }
79
80 pub fn database<S: Into<String>>(message: S) -> Self {
82 Self::Database {
83 message: message.into(),
84 }
85 }
86
87 pub fn storage<S: Into<String>>(message: S) -> Self {
89 Self::Storage {
90 message: message.into(),
91 }
92 }
93
94 pub fn realtime<S: Into<String>>(message: S) -> Self {
96 Self::Realtime {
97 message: message.into(),
98 }
99 }
100
101 pub fn config<S: Into<String>>(message: S) -> Self {
103 Self::Config {
104 message: message.into(),
105 }
106 }
107
108 pub fn invalid_input<S: Into<String>>(message: S) -> Self {
110 Self::InvalidInput {
111 message: message.into(),
112 }
113 }
114
115 pub fn network<S: Into<String>>(message: S) -> Self {
117 Self::Network {
118 message: message.into(),
119 }
120 }
121
122 pub fn rate_limit<S: Into<String>>(message: S) -> Self {
124 Self::RateLimit {
125 message: message.into(),
126 }
127 }
128
129 pub fn permission_denied<S: Into<String>>(message: S) -> Self {
131 Self::PermissionDenied {
132 message: message.into(),
133 }
134 }
135
136 pub fn not_found<S: Into<String>>(message: S) -> Self {
138 Self::NotFound {
139 message: message.into(),
140 }
141 }
142
143 pub fn generic<S: Into<String>>(message: S) -> Self {
145 Self::Generic {
146 message: message.into(),
147 }
148 }
149}
150
151impl From<reqwest::StatusCode> for Error {
153 fn from(status: reqwest::StatusCode) -> Self {
154 match status {
155 reqwest::StatusCode::UNAUTHORIZED => Self::auth("Unauthorized"),
156 reqwest::StatusCode::FORBIDDEN => Self::permission_denied("Forbidden"),
157 reqwest::StatusCode::NOT_FOUND => Self::not_found("Resource not found"),
158 reqwest::StatusCode::TOO_MANY_REQUESTS => Self::rate_limit("Too many requests"),
159 reqwest::StatusCode::INTERNAL_SERVER_ERROR => Self::network("Internal server error"),
160 reqwest::StatusCode::BAD_GATEWAY => Self::network("Bad gateway"),
161 reqwest::StatusCode::SERVICE_UNAVAILABLE => Self::network("Service unavailable"),
162 reqwest::StatusCode::GATEWAY_TIMEOUT => Self::network("Gateway timeout"),
163 _ => Self::network(format!("HTTP error: {}", status)),
164 }
165 }
166}