#[derive(Debug, thiserror::Error)] pub enum UpubError { #[error("database error: {0}")] Database(#[from] sea_orm::DbErr), #[error("api returned {0}")] Status(axum::http::StatusCode), #[error("missing field: {0}")] Field(#[from] crate::model::FieldError), #[error("openssl error: {0}")] OpenSSL(#[from] openssl::error::ErrorStack), #[error("invalid UTF8 in key: {0}")] OpenSSLParse(#[from] std::str::Utf8Error), #[error("fetch error: {0}")] Reqwest(#[from] reqwest::Error), } impl UpubError { pub fn bad_request() -> Self { Self::Status(axum::http::StatusCode::BAD_REQUEST) } pub fn unprocessable() -> Self { Self::Status(axum::http::StatusCode::UNPROCESSABLE_ENTITY) } pub fn not_found() -> Self { Self::Status(axum::http::StatusCode::NOT_FOUND) } pub fn forbidden() -> Self { Self::Status(axum::http::StatusCode::FORBIDDEN) } pub fn not_modified() -> Self { Self::Status(axum::http::StatusCode::NOT_MODIFIED) } pub fn internal_server_error() -> Self { Self::Status(axum::http::StatusCode::INTERNAL_SERVER_ERROR) } } pub type UpubResult = Result; impl From for UpubError { fn from(value: axum::http::StatusCode) -> Self { UpubError::Status(value) } } impl axum::response::IntoResponse for UpubError { fn into_response(self) -> axum::response::Response { ( axum::http::StatusCode::INTERNAL_SERVER_ERROR, self.to_string() ).into_response() } } pub trait LoggableError { fn info_failed(self, msg: &str); fn warn_failed(self, msg: &str); fn err_failed(self, msg: &str); } impl LoggableError for Result { fn info_failed(self, msg: &str) { if let Err(e) = self { tracing::info!("{} : {}", msg, e); } } fn warn_failed(self, msg: &str) { if let Err(e) = self { tracing::warn!("{} : {}", msg, e); } } fn err_failed(self, msg: &str) { if let Err(e) = self { tracing::error!("{} : {}", msg, e); } } }