autoendpoint/routers/apns/
error.rs1use crate::error::ApiErrorKind;
2use crate::routers::RouterError;
3use actix_web::http::StatusCode;
4use autopush_common::errors::ReportableError;
5use std::io;
6
7#[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 #[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 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 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}