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("Error while checking the message size limit: {0}")]
20 SizeLimit(#[source] a2::Error),
21
22 #[error("APNS error, {0}")]
23 ApnsUpstream(#[source] a2::Error),
24
25 #[error("APNS config, {0}:{1}")]
27 Config(String, String),
28
29 #[error("No device token found for user")]
30 NoDeviceToken,
31
32 #[error("No release channel found for user")]
33 NoReleaseChannel,
34
35 #[error("Release channel is invalid")]
36 InvalidReleaseChannel,
37
38 #[error("Invalid APS data")]
39 InvalidApsData,
40
41 #[error("APNS recipient no longer available")]
42 Unregistered,
43}
44
45impl ApnsError {
46 pub fn status(&self) -> StatusCode {
48 match self {
49 ApnsError::InvalidReleaseChannel
50 | ApnsError::InvalidApsData
51 | ApnsError::SizeLimit(_) => StatusCode::BAD_REQUEST,
52
53 ApnsError::NoDeviceToken | ApnsError::NoReleaseChannel | ApnsError::Unregistered => {
54 StatusCode::GONE
55 }
56
57 ApnsError::ChannelSettingsDecode(_)
58 | ApnsError::Io(_)
59 | ApnsError::ApnsClient(_)
60 | ApnsError::Config(..) => StatusCode::INTERNAL_SERVER_ERROR,
61
62 ApnsError::ApnsUpstream(_) => StatusCode::BAD_GATEWAY,
63 }
64 }
65
66 pub fn errno(&self) -> Option<usize> {
68 match self {
69 ApnsError::NoDeviceToken | ApnsError::NoReleaseChannel | ApnsError::Unregistered => {
70 Some(106)
71 }
72
73 ApnsError::ChannelSettingsDecode(_)
74 | ApnsError::Io(_)
75 | ApnsError::ApnsClient(_)
76 | ApnsError::ApnsUpstream(_)
77 | ApnsError::InvalidReleaseChannel
78 | ApnsError::InvalidApsData
79 | ApnsError::Config(..)
80 | ApnsError::SizeLimit(_) => None,
81 }
82 }
83}
84
85impl From<ApnsError> for ApiErrorKind {
86 fn from(e: ApnsError) -> Self {
87 ApiErrorKind::Router(RouterError::Apns(e))
88 }
89}
90
91impl ReportableError for ApnsError {
92 fn is_sentry_event(&self) -> bool {
93 !matches!(self, ApnsError::SizeLimit(_) | ApnsError::Unregistered)
94 }
95
96 fn metric_label(&self) -> Option<&'static str> {
97 match &self {
98 ApnsError::SizeLimit(_) => Some("notification.bridge.error.apns.oversized"),
99 ApnsError::ApnsUpstream(_) => Some("notification.bridge.error.apns.upstream"),
100 _ => None,
101 }
102 }
103
104 fn extras(&self) -> Vec<(&str, String)> {
105 match self {
106 ApnsError::ApnsUpstream(e) => vec![("error", e.to_string())],
107 _ => vec![],
108 }
109 }
110}