yao-dev-common 0.1.10

Common library
Documentation
use crate::error::repo_error::RepoError;
use anyhow::Error;
use axum::http::StatusCode;
use axum::response::{IntoResponse, Response};
use axum::Json;
use serde_json::json;

#[derive(Debug, thiserror::Error)]
pub enum AppError {
    #[allow(dead_code)]
    #[error("Unauthorized: {0}")]
    Unauthorized(String), // 401

    #[allow(dead_code)]
    #[error("Invalid params: {0:?}")]
    InvalidParams(Vec<&'static str>), // 400

    #[allow(dead_code)]
    #[error("Error parsing `multipart/form-data` request.\n{0}")]
    MultipartError(String), // 400

    #[allow(dead_code)]
    #[error("Not Found: {0}")]
    NotFound(&'static str), // 404

    #[allow(dead_code)]
    #[error("Internal Server Error: {0}")]
    InternalServerError(#[from] anyhow::Error), // 500

    #[allow(dead_code)]
    #[error("Json parse Error: {0}")]
    JsonError(#[from] serde_json::Error),

    #[allow(dead_code)]
    #[error("Reqwest Error: {0}")]
    ReqwestError(#[from] reqwest::Error),

    #[allow(dead_code)]
    #[error("Askama Error: {0}")]
    AskamaError(#[from] askama::Error),

    #[allow(dead_code)]
    #[error("Custom Error: {0}")]
    CustomError(String), // 500
}

impl IntoResponse for AppError {
    fn into_response(self) -> Response {
        let (status, error_message) = match self {
            AppError::Unauthorized(_) => (StatusCode::UNAUTHORIZED, self.to_string()), // 401
            AppError::InvalidParams(_) => (StatusCode::BAD_REQUEST, self.to_string()), // 400
            AppError::MultipartError(_) => (StatusCode::BAD_REQUEST, self.to_string()), // 400
            AppError::NotFound(_) => (StatusCode::NOT_FOUND, self.to_string()),        // 404
            AppError::JsonError(_) => (StatusCode::INTERNAL_SERVER_ERROR, self.to_string()), // 500
            AppError::ReqwestError(_) => (StatusCode::INTERNAL_SERVER_ERROR, self.to_string()), // 500
            AppError::AskamaError(_) => (StatusCode::INTERNAL_SERVER_ERROR, self.to_string()), // 500
            AppError::InternalServerError(_) => {
                (StatusCode::INTERNAL_SERVER_ERROR, self.to_string())
            } // 500
            AppError::CustomError(_) => (StatusCode::INTERNAL_SERVER_ERROR, self.to_string()), // 500
        };
        let body = Json(json!({"error": error_message}));
        (status, body).into_response()
    }
}

impl From<RepoError> for AppError {
    fn from(error: RepoError) -> Self {
        AppError::InternalServerError(Error::from(error))
    }
}

impl From<&str> for AppError {
    fn from(msg: &str) -> Self {
        AppError::CustomError(msg.to_string())
    }
}

impl From<String> for AppError {
    fn from(msg: String) -> Self {
        AppError::CustomError(msg)
    }
}