1use axum::{http::StatusCode, response::IntoResponse};
2
3pub type Result<T, E = Error> = std::result::Result<T, E>;
4
5pub enum Error {
6 Http(StatusCode, String),
7 Database(sqlx::Error),
8 Internal(anyhow::Error),
9}
10
11impl From<anyhow::Error> for Error {
12 fn from(error: anyhow::Error) -> Self {
13 Self::Internal(error)
14 }
15}
16
17impl From<sqlx::Error> for Error {
18 fn from(error: sqlx::Error) -> Self {
19 Self::Database(error)
20 }
21}
22
23impl From<axum::Error> for Error {
24 fn from(error: axum::Error) -> Self {
25 Self::Internal(error.into())
26 }
27}
28
29impl From<hyper::Error> for Error {
30 fn from(error: hyper::Error) -> Self {
31 Self::Internal(error.into())
32 }
33}
34
35impl From<serde_json::Error> for Error {
36 fn from(error: serde_json::Error) -> Self {
37 Self::Internal(error.into())
38 }
39}
40
41impl IntoResponse for Error {
42 fn into_response(self) -> axum::response::Response {
43 match self {
44 Error::Http(code, message) => (code, message).into_response(),
45 Error::Database(error) => {
46 (StatusCode::INTERNAL_SERVER_ERROR, format!("{}", &error)).into_response()
47 }
48 Error::Internal(error) => {
49 (StatusCode::INTERNAL_SERVER_ERROR, format!("{}", &error)).into_response()
50 }
51 }
52 }
53}
54
55impl std::fmt::Debug for Error {
56 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
57 match self {
58 Error::Http(code, message) => (code, message).fmt(f),
59 Error::Database(error) => error.fmt(f),
60 Error::Internal(error) => error.fmt(f),
61 }
62 }
63}
64
65impl std::fmt::Display for Error {
66 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
67 match self {
68 Error::Http(code, message) => write!(f, "{code}: {message}"),
69 Error::Database(error) => error.fmt(f),
70 Error::Internal(error) => error.fmt(f),
71 }
72 }
73}
74
75impl std::error::Error for Error {}