bark_apns/error.rs
1/// Result type used by this crate.
2///
3/// The default error type is [`Error`], but the alias accepts a custom error
4/// parameter when needed.
5pub type Result<T, E = Error> = std::result::Result<T, E>;
6
7/// Error type for Bark APNs operations.
8///
9/// The enum is non-exhaustive so the crate can add more precise variants later
10/// without breaking downstream code. Applications can convert it into
11/// `anyhow::Error` with `?`, while libraries can match individual variants.
12#[non_exhaustive]
13#[derive(Debug, thiserror::Error)]
14pub enum Error {
15 /// The encryption key length does not match the selected AES algorithm.
16 #[error(
17 "invalid encryption key length for {algorithm}: expected {expected} bytes, got {actual}"
18 )]
19 InvalidKeyLength {
20 /// Bark algorithm name, such as `AES128`.
21 algorithm: &'static str,
22 /// Expected UTF-8 byte length.
23 expected: usize,
24 /// Actual UTF-8 byte length.
25 actual: usize,
26 },
27
28 /// The message id is too long to be used as an APNs collapse id.
29 #[error("invalid APNs collapse id: expected at most 64 bytes, got {actual}")]
30 InvalidCollapseId {
31 /// Actual UTF-8 byte length.
32 actual: usize,
33 },
34
35 /// A delete message was serialized or sent without an id.
36 #[error("delete messages require an id")]
37 MissingMessageIdForDelete,
38
39 /// A normal non-delete message has neither body nor markdown.
40 #[error("message body or markdown is required")]
41 EmptyMessage,
42
43 /// An encrypted message was sent to a device without encryption settings.
44 #[error("encrypted messages require encryption settings for device {device}")]
45 MissingDeviceEncryption {
46 /// Normalized iOS device token.
47 device: String,
48 },
49
50 /// A value could not be encoded as an APNs HTTP header.
51 #[error("invalid APNs header value for {name}: {source}")]
52 InvalidHeaderValue {
53 /// Header name being constructed.
54 name: &'static str,
55 /// Underlying header parsing error.
56 #[source]
57 source: reqwest::header::InvalidHeaderValue,
58 },
59
60 /// The HTTP client could not be constructed.
61 #[error("failed to build HTTP client: {0}")]
62 HttpClient(#[source] reqwest::Error),
63
64 /// An HTTP request failed before receiving a per-device APNs response.
65 #[error("APNs request failed: {0}")]
66 Http(#[from] reqwest::Error),
67
68 /// APNs provider-token generation failed.
69 #[error("APNs token generation failed: {0}")]
70 Jwt(#[from] jsonwebtoken::errors::Error),
71
72 /// JSON serialization failed.
73 #[error("failed to serialize payload: {0}")]
74 Json(#[from] serde_json::Error),
75
76 /// Encryption failed after input validation.
77 #[error("encryption failed")]
78 Encryption,
79
80 /// Random IV generation failed.
81 #[error("failed to generate random IV: {0}")]
82 Random(
83 /// Randomness provider error text.
84 String,
85 ),
86
87 /// One or more device tokens failed during a multi-device send.
88 #[error("APNs failed for one or more devices: {0}")]
89 ApnsFailures(
90 /// Human-readable summary containing failed device tokens and reasons.
91 String,
92 ),
93}
94
95impl From<getrandom::Error> for Error {
96 fn from(error: getrandom::Error) -> Self {
97 Self::Random(error.to_string())
98 }
99}