use axum::http::StatusCode;
use axum::response::{IntoResponse, Response};
use axum::Json;
use dialtone_common::ap::id::IdError;
use dialtone_common::rest::simple_exchanges::SimpleResponse;
use dialtone_common::utils::parse_acct::ParseUserAcctError;
#[derive(Debug)]
pub enum ResponseError {
WrongCredentials(Option<String>),
MissingCredentials(Option<String>),
TokenDecodingError(Option<String>),
TokenCreation(Option<String>),
BadTokenInHeader(Option<String>),
UnableToAuthenticate(Option<String>),
NoAuthorizationsAvailable(Option<String>),
UnableToAuthorize(Option<String>),
BadRequest(Option<String>),
NotFound(Option<String>),
InternalServerError(Option<String>),
}
impl ResponseError {
pub fn not_found() -> ResponseError {
ResponseError::NotFound(None)
}
}
impl IntoResponse for ResponseError {
fn into_response(self) -> Response {
let (status, error_message, log_msg) = match self {
ResponseError::WrongCredentials(ref log_msg) => {
(StatusCode::FORBIDDEN, "Wrong credentials", log_msg)
}
ResponseError::MissingCredentials(ref log_msg) => {
(StatusCode::UNAUTHORIZED, "Missing credentials", log_msg)
}
ResponseError::TokenDecodingError(ref log_msg) => {
(StatusCode::BAD_REQUEST, "Token decoding error", log_msg)
}
ResponseError::TokenCreation(ref log_msg) => (
StatusCode::INTERNAL_SERVER_ERROR,
"Token creation error",
log_msg,
),
ResponseError::BadTokenInHeader(ref log_msg) => {
(StatusCode::BAD_REQUEST, "Bad token in header", log_msg)
}
ResponseError::UnableToAuthenticate(ref log_msg) => {
(StatusCode::UNAUTHORIZED, "Wrong credentials", log_msg)
}
ResponseError::NoAuthorizationsAvailable(ref log_msg) => (
StatusCode::FORBIDDEN,
"No authorizations available",
log_msg,
),
ResponseError::UnableToAuthorize(ref log_msg) => {
(StatusCode::FORBIDDEN, "Unable to authorize", log_msg)
}
ResponseError::BadRequest(ref log_msg) => {
(StatusCode::BAD_REQUEST, "Bad request", log_msg)
}
ResponseError::NotFound(ref log_msg) => (StatusCode::NOT_FOUND, "Not found", log_msg),
ResponseError::InternalServerError(ref log_msg) => (
StatusCode::INTERNAL_SERVER_ERROR,
"Internal server error",
log_msg,
),
};
if let Some(log_msg) = log_msg {
match self {
ResponseError::InternalServerError(_) => tracing::error!("{}", log_msg),
_ => tracing::warn!("{}", log_msg),
}
}
let body = Json(SimpleResponse::failure_with_msg(error_message));
(status, body).into_response()
}
}
impl From<sqlx::Error> for ResponseError {
fn from(err: sqlx::Error) -> Self {
ResponseError::InternalServerError(Some(err.to_string()))
}
}
impl From<anyhow::Error> for ResponseError {
fn from(err: anyhow::Error) -> Self {
ResponseError::InternalServerError(Some(err.to_string()))
}
}
impl From<IdError> for ResponseError {
fn from(err: IdError) -> Self {
ResponseError::BadRequest(Some(err.to_string()))
}
}
impl From<ParseUserAcctError> for ResponseError {
fn from(_err: ParseUserAcctError) -> Self {
ResponseError::BadRequest(None)
}
}