Skip to main content

affinidi_did_resolver_cache_server/
errors.rs

1use axum::{
2    Json,
3    http::StatusCode,
4    response::{IntoResponse, Response},
5};
6use serde::{Deserialize, Serialize};
7use std::fmt;
8use thiserror::Error;
9use tracing::{Level, event};
10
11use crate::common::GenericDataStruct;
12
13type SessId = String;
14
15pub struct AppError(CacheError);
16
17impl<E> From<E> for AppError
18where
19    E: Into<CacheError>,
20{
21    fn from(err: E) -> Self {
22        Self(err.into())
23    }
24}
25
26/// CacheError the first String is always the session_id
27#[derive(Error, Debug)]
28#[non_exhaustive]
29pub enum CacheError {
30    #[error("Error in handling errors! {1}")]
31    ErrorHandlingError(SessId, String),
32    #[error("{1}")]
33    InternalError(SessId, String),
34    #[error("Couldn't parse ({1}). Reason: {2}")]
35    ParseError(SessId, String, String),
36    #[error("DID Error: did({1}) Error: {2}")]
37    DIDError(SessId, String, String),
38    #[error("Configuration Error: {1}")]
39    ConfigError(SessId, String),
40}
41
42impl IntoResponse for AppError {
43    fn into_response(self) -> Response {
44        let response = match self.0 {
45            CacheError::ErrorHandlingError(session_id, msg) => {
46                let response = ErrorResponse {
47                    httpCode: StatusCode::INTERNAL_SERVER_ERROR.as_u16(),
48                    sessionId: session_id.to_string(),
49                    errorCode: 1,
50                    errorCodeStr: "ErrorHandlingError".to_string(),
51                    message: msg.to_string(),
52                };
53                event!(Level::WARN, "{}", response.to_string());
54                response
55            }
56            CacheError::InternalError(session_id, msg) => {
57                let response = ErrorResponse {
58                    httpCode: StatusCode::INTERNAL_SERVER_ERROR.as_u16(),
59                    sessionId: session_id.to_string(),
60                    errorCode: 2,
61                    errorCodeStr: "InternalError".to_string(),
62                    message: msg.to_string(),
63                };
64                event!(Level::WARN, "{}", response.to_string());
65                response
66            }
67            CacheError::ParseError(session_id, _, msg) => {
68                let response = ErrorResponse {
69                    httpCode: StatusCode::BAD_REQUEST.as_u16(),
70                    sessionId: session_id.to_string(),
71                    errorCode: 3,
72                    errorCodeStr: "BadRequest: ParseError".to_string(),
73                    message: msg.to_string(),
74                };
75                event!(Level::WARN, "{}", response.to_string());
76                response
77            }
78            CacheError::DIDError(session_id, did, msg) => {
79                let response = ErrorResponse {
80                    httpCode: StatusCode::BAD_REQUEST.as_u16(),
81                    sessionId: session_id.to_string(),
82                    errorCode: 8,
83                    errorCodeStr: "DIDError".to_string(),
84                    message: format!("did({did}) Error: {msg}"),
85                };
86                event!(Level::WARN, "{}", response.to_string());
87                response
88            }
89            CacheError::ConfigError(session_id, message) => {
90                let response = ErrorResponse {
91                    httpCode: StatusCode::SERVICE_UNAVAILABLE.as_u16(),
92                    sessionId: session_id.to_string(),
93                    errorCode: 9,
94                    errorCodeStr: "ConfigError".to_string(),
95                    message,
96                };
97                event!(Level::WARN, "{}", response.to_string());
98                response
99            }
100        };
101        (
102            StatusCode::from_u16(response.httpCode).unwrap_or(StatusCode::INTERNAL_SERVER_ERROR),
103            Json(response),
104        )
105            .into_response()
106    }
107}
108
109#[derive(Serialize, Debug)]
110#[allow(non_snake_case)]
111pub struct ErrorResponse {
112    pub sessionId: String,
113    pub httpCode: u16,
114    pub errorCode: u16,
115    pub errorCodeStr: String,
116    pub message: String,
117}
118
119impl fmt::Display for ErrorResponse {
120    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
121        write!(
122            f,
123            "{}: httpcode({}) errorCode({}), errorCodeStr({}) message({})",
124            self.sessionId, self.httpCode, self.errorCode, self.errorCodeStr, self.message,
125        )
126    }
127}
128#[derive(Serialize, Deserialize, Debug)]
129#[allow(non_snake_case)]
130pub struct SuccessResponse<T: GenericDataStruct> {
131    pub sessionId: String,
132    pub httpCode: u16,
133    pub errorCode: i32,
134    pub errorCodeStr: String,
135    pub message: String,
136    #[serde(bound(deserialize = ""))]
137    pub data: Option<T>,
138}
139
140impl<T: GenericDataStruct> fmt::Display for SuccessResponse<T> {
141    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
142        write!(
143            f,
144            "{}: httpcode({}) errorCode({}), errorCodeStr({}) message({})",
145            self.sessionId, self.httpCode, self.errorCode, self.errorCodeStr, self.message,
146        )
147    }
148}
149
150impl<T: GenericDataStruct> SuccessResponse<T> {
151    pub fn response(
152        session_id: &str,
153        http_code: StatusCode,
154        msg: &str,
155        data: Option<T>,
156    ) -> Json<SuccessResponse<T>> {
157        let response = SuccessResponse {
158            sessionId: session_id.to_string(),
159            httpCode: http_code.as_u16(),
160            errorCode: 0,
161            errorCodeStr: "Ok".to_string(),
162            message: msg.to_string(),
163            data,
164        };
165        event!(Level::INFO, "{response}");
166        Json(response)
167    }
168}