use axum::response::{IntoResponse, Response}; use http::StatusCode; use tracing::{error, field}; use ulid::Ulid; #[derive(Debug, thiserror::Error)] pub enum AppError { #[error("link already exists ({0})")] LinkExists(Ulid), #[error("link not found ({0})")] LinkNotFound(Ulid), #[error("database returned an impossible number of affected rows ({0})")] ImpossibleAffectedRows(u64), #[error("database error")] Database(#[from] sqlx::Error), #[error(transparent)] Other(#[from] eyre::Report), } impl IntoResponse for AppError { fn into_response(self) -> Response { error!(err = field::display(&self)); match self { Self::LinkExists(_) => (StatusCode::BAD_REQUEST, "Link already exists").into_response(), Self::LinkNotFound(_) => (StatusCode::NOT_FOUND, "Link not found").into_response(), Self::ImpossibleAffectedRows(_) => ( StatusCode::INTERNAL_SERVER_ERROR, "Database returned an impossible number of affected rows", ) .into_response(), Self::Database(_) => ( StatusCode::INTERNAL_SERVER_ERROR, "A database error has occured", ) .into_response(), Self::Other(err) => ( StatusCode::INTERNAL_SERVER_ERROR, format!("An error has occured:\n{err:?}"), ) .into_response(), } } }