1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
pub use actix_web::http::StatusCode;
pub use std::fmt::{{Display, Formatter, Debug}};

use serde::Serialize;
pub use actix_error_derive::AsApiError;

#[derive(Debug, Clone, Serialize)]
pub struct ApiError {
    pub kind: String,
    #[serde(skip_serializing)]
    pub code: u16,
    pub message: String,
}

impl ApiError {
    pub fn new(code: u16, kind: &str, message: String) -> Self {
        Self {
            kind: kind.to_string(),
            message,
            code,
        }
    }
}

pub trait AsApiErrorTrait {
    fn as_api_error(&self) -> ApiError;
}

impl std::fmt::Display for ApiError {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "{} : {}", self.kind, self.message)
    }
}

impl actix_web::ResponseError for ApiError {
    fn status_code(&self) -> StatusCode {
        StatusCode::from_u16(self.code).unwrap_or(StatusCode::INTERNAL_SERVER_ERROR)
    }

    fn error_response(&self) -> actix_web::HttpResponse {
        actix_web::HttpResponse::build(self.status_code()).json(self)
    }
}