1use thiserror::Error;
2
3#[derive(Error, Debug)]
4pub enum Error {
5 #[error("Internal server error: {0}")]
6 InternalServerError(String),
7 #[error("Resource not found: {0}")]
8 NotFound(String),
9 #[error("Bad request: {0}")]
10 BadRequest(String),
11 #[error("Unauthorized access: {0}")]
12 Unauthorized(String),
13 #[error("Forbidden: {0}")]
14 Forbidden(String),
15 #[error("Resource conflict: {0}")]
16 Conflict(String),
17 #[error("Validation failed: {0}")]
18 Validation(String),
19 #[error("Rate limit exceeded: {0}")]
20 RateLimited(String),
21 #[error("Service temporarily unavailable: {0}")]
22 ServiceUnavailable(String),
23 #[error("Method not allowed: {0}")]
24 MethodNotAllowed(String),
25 #[error(transparent)]
26 Hyper(#[from] hyper::Error),
27 #[error(transparent)]
28 Io(#[from] std::io::Error),
29 #[error(transparent)]
30 SerdeJson(#[from] serde_json::Error),
31 #[error(transparent)]
32 SerdeUrlEncoded(#[from] serde_urlencoded::de::Error),
33 #[error(transparent)]
34 Http(#[from] http::Error),
35 #[error(transparent)]
36 Utf8(#[from] std::str::Utf8Error),
37}
38
39pub type Result<T> = std::result::Result<T, Error>;
41
42impl Error {
43 pub fn status_code(&self) -> hyper::StatusCode {
45 match self {
46 Error::NotFound(_) => hyper::StatusCode::NOT_FOUND,
47 Error::BadRequest(_) | Error::SerdeJson(_) | Error::SerdeUrlEncoded(_) | Error::Utf8(_) => hyper::StatusCode::BAD_REQUEST,
48 Error::Unauthorized(_) => hyper::StatusCode::UNAUTHORIZED,
49 Error::Forbidden(_) => hyper::StatusCode::FORBIDDEN,
50 Error::Conflict(_) => hyper::StatusCode::CONFLICT,
51 Error::Validation(_) => hyper::StatusCode::UNPROCESSABLE_ENTITY,
52 Error::RateLimited(_) => hyper::StatusCode::TOO_MANY_REQUESTS,
53 Error::ServiceUnavailable(_) => hyper::StatusCode::SERVICE_UNAVAILABLE,
54 Error::MethodNotAllowed(_) => hyper::StatusCode::METHOD_NOT_ALLOWED,
55 Error::InternalServerError(_) | Error::Hyper(_) | Error::Io(_) | Error::Http(_) => hyper::StatusCode::INTERNAL_SERVER_ERROR,
56 }
57 }
58
59 pub fn is_client_error(&self) -> bool {
62 let status = self.status_code();
63 status.is_client_error()
64 }
65
66 pub fn is_server_error(&self) -> bool {
69 let status = self.status_code();
70 status.is_server_error()
71 }
72}