use axum::http::StatusCode; pub type Result = std::result::Result; #[derive(thiserror::Error, Debug)] pub enum Error { #[error("IO error: {0}")] IO(#[from] std::io::Error), #[error("Config file error: {0}")] Toml(#[from] toml::de::Error), #[error("Config error: {0}")] Config(String), #[error("Axum error: {0}")] Axum(#[from] axum::Error), #[error("Http error: {0}")] Http(#[from] axum::http::Error), #[error("Header error: {0}")] Header(#[from] axum::http::header::InvalidHeaderValue), #[error("Json error: {0}")] Json(#[from] serde_json::Error), #[error("Time error: {0}")] Time(#[from] time::error::ComponentRange), #[error("JSON web token error: {0}")] Jwt(#[from] jsonwebtoken::errors::Error), #[error("Token error: {0}")] Token(#[from] axum_extra::headers::authorization::InvalidBearerToken), #[error("Database error: {0}")] Sqlx(#[from] sqlx::Error), #[error("Migration error: {0}")] Migration(#[from] sqlx::migrate::MigrateError), #[error("Route not found: {0}")] RouteNotFound(axum::http::Uri), #[error("User not found")] UserNotFound, #[error("Invalid user token")] InvalidToken, #[error("User with that email already exists")] EmailExists, #[error("Invalid email: {0}")] EmailInvalid(#[from] email_address::Error), #[error("Invalid email or password")] Authorization(#[from] crate::auth::error::Error), #[error("{0}")] Other(String), } impl axum::response::IntoResponse for Error { fn into_response(self) -> axum::response::Response { // TODO: implement [rfc7807](https://www.rfc-editor.org/rfc/rfc7807.html) let status = match &self { Self::RouteNotFound(_) | Self::UserNotFound => StatusCode::NOT_FOUND, Self::EmailExists => StatusCode::CONFLICT, Self::EmailInvalid(_) => StatusCode::UNPROCESSABLE_ENTITY, Self::InvalidToken | Self::Authorization(_) => StatusCode::UNAUTHORIZED, _ => StatusCode::INTERNAL_SERVER_ERROR, }; (status, self.to_string()).into_response() } }