autoendpoint/routers/apns/
error.rs

1use crate::error::ApiErrorKind;
2use crate::routers::RouterError;
3use actix_web::http::StatusCode;
4use autopush_common::errors::ReportableError;
5use std::io;
6
7/// Errors that may occur in the Apple Push Notification Service router
8#[derive(thiserror::Error, Debug)]
9pub enum ApnsError {
10    #[error("Failed to decode the channel settings")]
11    ChannelSettingsDecode(#[from] serde_json::Error),
12
13    #[error("IO Error: {0}")]
14    Io(#[from] io::Error),
15
16    #[error("Error while setting up APNS clients: {0}")]
17    ApnsClient(#[source] a2::Error),
18
19    #[error("APNS error, {0}")]
20    ApnsUpstream(#[source] a2::Error),
21
22    /// Configuration error {Type of error}, {Error string}
23    #[error("APNS config, {0}:{1}")]
24    Config(String, String),
25
26    #[error("No device token found for user")]
27    NoDeviceToken,
28
29    #[error("No release channel found for user")]
30    NoReleaseChannel,
31
32    #[error("Release channel is invalid")]
33    InvalidReleaseChannel,
34
35    #[error("Invalid APS data")]
36    InvalidApsData,
37
38    #[error("APNS recipient no longer available")]
39    Unregistered,
40}
41
42impl ApnsError {
43    /// Get the associated HTTP status code
44    pub fn status(&self) -> StatusCode {
45        match self {
46            ApnsError::InvalidReleaseChannel | ApnsError::InvalidApsData => StatusCode::BAD_REQUEST,
47
48            ApnsError::NoDeviceToken | ApnsError::NoReleaseChannel | ApnsError::Unregistered => {
49                StatusCode::GONE
50            }
51
52            ApnsError::ChannelSettingsDecode(_)
53            | ApnsError::Io(_)
54            | ApnsError::ApnsClient(_)
55            | ApnsError::Config(..) => StatusCode::INTERNAL_SERVER_ERROR,
56
57            ApnsError::ApnsUpstream(_) => StatusCode::BAD_GATEWAY,
58        }
59    }
60
61    /// Get the associated error number
62    pub fn errno(&self) -> Option<usize> {
63        match self {
64            ApnsError::NoDeviceToken | ApnsError::NoReleaseChannel | ApnsError::Unregistered => {
65                Some(106)
66            }
67
68            ApnsError::ChannelSettingsDecode(_)
69            | ApnsError::Io(_)
70            | ApnsError::ApnsClient(_)
71            | ApnsError::ApnsUpstream(_)
72            | ApnsError::InvalidReleaseChannel
73            | ApnsError::InvalidApsData
74            | ApnsError::Config(..) => None,
75        }
76    }
77}
78
79impl From<ApnsError> for ApiErrorKind {
80    fn from(e: ApnsError) -> Self {
81        ApiErrorKind::Router(RouterError::Apns(e))
82    }
83}
84
85impl ReportableError for ApnsError {
86    fn is_sentry_event(&self) -> bool {
87        !matches!(self, ApnsError::Unregistered)
88    }
89
90    fn metric_label(&self) -> Option<&'static str> {
91        match &self {
92            ApnsError::ApnsUpstream(_) => Some("notification.bridge.error.apns.upstream"),
93            _ => None,
94        }
95    }
96
97    fn extras(&self) -> Vec<(&str, String)> {
98        match self {
99            ApnsError::ApnsUpstream(e) => vec![("error", e.to_string())],
100            _ => vec![],
101        }
102    }
103}