libsignal_service/push_service/
error.rs

1use aes::cipher::block_padding::UnpadError;
2use libsignal_core::curve::CurveError;
3use libsignal_protocol::{
4    FingerprintError, ServiceIdKind, SignalProtocolError,
5};
6use zkgroup::{ZkGroupDeserializationFailure, ZkGroupVerificationFailure};
7
8use crate::{
9    cipher::SealedSenderDecryptionError, groups_v2::GroupDecodingError,
10    websocket::registration::RegistrationLockFailure,
11};
12
13use super::{MismatchedDevices, ProofRequired, StaleDevices};
14
15#[derive(thiserror::Error, Debug)]
16pub enum ServiceError {
17    #[error("Service request timed out: {reason}")]
18    Timeout { reason: &'static str },
19
20    #[error("invalid URL: {0}")]
21    InvalidUrl(#[from] url::ParseError),
22
23    #[error("wrong address type: {0}")]
24    InvalidAddressType(ServiceIdKind),
25
26    #[error("invalid phone number")]
27    InvalidPhoneNumber,
28
29    #[error("Error sending request: {reason}")]
30    SendError { reason: String },
31
32    #[error("i/o error")]
33    IO(#[from] std::io::Error),
34
35    #[error("Error decoding JSON: {0}")]
36    JsonDecodeError(#[from] serde_json::Error),
37    #[error("Error decoding protobuf frame: {0}")]
38    ProtobufDecodeError(#[from] prost::DecodeError),
39    #[error("error encoding or decoding bincode: {0}")]
40    BincodeError(#[from] bincode::Error),
41    #[error("error decoding base64 string: {0}")]
42    Base64DecodeError(#[from] base64::DecodeError),
43
44    #[error("Rate limit exceeded: retry after {}", retry_after.map(|a| a.to_string()).unwrap_or_else(|| "unspecified".into()))]
45    RateLimitExceeded {
46        retry_after: Option<chrono::Duration>,
47    },
48    #[error("Authorization failed")]
49    Unauthorized,
50    #[error("Registration lock is set: {0:?}")]
51    Locked(RegistrationLockFailure),
52    #[error("Unexpected response: HTTP {http_code}")]
53    UnhandledResponseCode { http_code: u16 },
54
55    #[error("Websocket error: {0}")]
56    WsError(Box<reqwest_websocket::Error>),
57    #[error("Websocket closing: {reason}")]
58    WsClosing { reason: &'static str },
59
60    #[error("Invalid padding: {0}")]
61    Padding(#[from] UnpadError),
62
63    #[error("unknown padding version {0}")]
64    PaddingVersion(u32),
65
66    #[error("Invalid frame: {reason}")]
67    InvalidFrame { reason: &'static str },
68
69    #[error("MAC error")]
70    MacError,
71
72    #[error("Protocol error: {0}")]
73    SignalProtocolError(#[from] SignalProtocolError),
74
75    #[error("Sealed sender decryption error: {0}")]
76    SealedSenderDecryptionError(#[from] SealedSenderDecryptionError),
77
78    #[error("invalid device id: {0}")]
79    InvalidDeviceId(#[from] libsignal_core::InvalidDeviceId),
80
81    #[error("Proof required: {0:?}")]
82    ProofRequiredError(ProofRequired),
83
84    #[error("{0:?}")]
85    MismatchedDevicesException(MismatchedDevices),
86
87    #[error("{0:?}")]
88    StaleDevices(StaleDevices),
89
90    #[error(transparent)]
91    CredentialsCacheError(#[from] crate::groups_v2::CredentialsCacheError),
92
93    #[error("groups v2 (zero-knowledge) error")]
94    GroupsV2Error,
95
96    #[error(transparent)]
97    GroupsV2DecryptionError(#[from] GroupDecodingError),
98
99    #[error(transparent)]
100    ZkGroupDeserializationFailure(#[from] ZkGroupDeserializationFailure),
101
102    #[error(transparent)]
103    ZkGroupVerificationFailure(#[from] ZkGroupVerificationFailure),
104
105    #[error("unsupported content")]
106    UnsupportedContent,
107
108    #[error("Not found.")]
109    NotFoundError,
110
111    #[error("failed to decrypt field from device info: {0}")]
112    DecryptDeviceInfoFieldError(&'static str),
113
114    #[error("Unknown CDN version {0}")]
115    UnknownCdnVersion(u32),
116
117    #[error("Device limit reached: {current} out of {max} devices.")]
118    DeviceLimitReached { current: u32, max: u32 },
119
120    #[error("HTTP reqwest error: {0}")]
121    Http(#[from] reqwest::Error),
122
123    #[error(transparent)]
124    Curve(#[from] CurveError),
125
126    // HpkeError does not implement StdError, so we need a manual display,
127    // and manual From impl.
128    #[error("Cryptographic error: {0}")]
129    Hpke(signal_crypto::HpkeError),
130
131    // FingerprintError does not implement StdError, so we need a manual display,
132    // and manual From impl.
133    #[error("Fingerprint error: {0}")]
134    Fingerprint(FingerprintError),
135
136    #[error("CDSI lookup error: {0}")]
137    #[cfg(feature = "cdsi")]
138    CdsiLookupError(#[from] libsignal_net::cdsi::LookupError),
139}
140
141impl From<signal_crypto::HpkeError> for ServiceError {
142    fn from(value: signal_crypto::HpkeError) -> Self {
143        ServiceError::Hpke(value)
144    }
145}
146
147impl From<FingerprintError> for ServiceError {
148    fn from(value: FingerprintError) -> Self {
149        ServiceError::Fingerprint(value)
150    }
151}
152
153impl From<reqwest_websocket::Error> for ServiceError {
154    fn from(error: reqwest_websocket::Error) -> Self {
155        Self::WsError(Box::new(error))
156    }
157}