autoconnect_web/
error.rs

1use actix_http::ws::HandshakeError;
2use actix_web::{error::ResponseError, http::StatusCode, HttpResponse};
3use serde_json::json;
4
5use autopush_common::errors::ReportableError;
6
7/// The main error type
8#[derive(thiserror::Error, Debug)]
9pub enum ApiError {
10    #[error("Actix Web error: {0}")]
11    Actix(#[from] actix_web::error::Error),
12
13    #[error("LogCheck")]
14    LogCheck,
15}
16
17impl ResponseError for ApiError {
18    fn status_code(&self) -> StatusCode {
19        match self {
20            ApiError::Actix(e) => e.as_response_error().status_code(),
21            ApiError::LogCheck => StatusCode::IM_A_TEAPOT,
22        }
23    }
24
25    fn error_response(&self) -> HttpResponse {
26        let code = self.status_code();
27        HttpResponse::build(code).json(json!({
28            "code": code.as_u16(),
29            "errno": self.errno(),
30            "error": self.to_string(),
31        }))
32    }
33}
34
35impl ReportableError for ApiError {
36    fn is_sentry_event(&self) -> bool {
37        match self {
38            // Ignore failing upgrade to WebSocket
39            ApiError::Actix(e) => e.as_error::<HandshakeError>().is_none(),
40            _ => true,
41        }
42    }
43}
44
45impl ApiError {
46    /// Return a unique errno code per variant
47    pub fn errno(&self) -> i32 {
48        match self {
49            ApiError::Actix(_) => 500,
50            ApiError::LogCheck => 999,
51        }
52    }
53}