Skip to main content

cargo_smith/common/
errors.rs

1use actix_web::{HttpResponse, ResponseError, http::StatusCode};
2use std::fmt;
3
4use crate::common::response::ApiResponse;
5
6#[derive(Debug)]
7pub enum AppError {
8    Unauthorized(&'static str),
9    Forbidden(&'static str),
10    NotFound(String),
11    BadRequest(String),
12    Internal(String),
13    Database(mongodb::error::Error),
14}
15
16impl fmt::Display for AppError {
17    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
18        match self {
19            Self::Unauthorized(msg) => write!(f, "{}", msg),
20            Self::Forbidden(msg) => write!(f, "{}", msg),
21            Self::NotFound(msg) => write!(f, "{}", msg),
22            Self::BadRequest(msg) => write!(f, "{}", msg),
23            Self::Internal(msg) => write!(f, "{}", msg),
24            Self::Database(e) => write!(f, "database error: {}", e),
25        }
26    }
27}
28
29impl ResponseError for AppError {
30
31    fn status_code(&self) -> StatusCode {
32        match self {
33            Self::Unauthorized(_) => StatusCode::UNAUTHORIZED,
34            Self::Forbidden(_) => StatusCode::FORBIDDEN,
35            Self::NotFound(_) => StatusCode::NOT_FOUND,
36            Self::BadRequest(_) => StatusCode::BAD_REQUEST,
37            Self::Internal(_) | Self::Database(_) => StatusCode::INTERNAL_SERVER_ERROR,
38        }
39    }
40
41    fn error_response(&self) -> HttpResponse {
42        
43        let status = self.status_code();
44
45        let body = ApiResponse::<()>::message(status, self.to_string());
46        
47        HttpResponse::build(status).json(body)
48    }
49}
50
51// So you can do mongo_result.map_err(AppError::Database)?
52impl From<mongodb::error::Error> for AppError {
53    fn from(e: mongodb::error::Error) -> Self {
54        Self::Database(e)
55    }
56}