libsignal_service/push_service/
error.rs1use 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 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("invalid device id: {0}")]
76 InvalidDeviceId(#[from] libsignal_core::InvalidDeviceId),
77
78 #[error("Proof required: {0:?}")]
79 ProofRequiredError(ProofRequired),
80
81 #[error("{0:?}")]
82 MismatchedDevicesException(MismatchedDevices),
83
84 #[error("{0:?}")]
85 StaleDevices(StaleDevices),
86
87 #[error(transparent)]
88 CredentialsCacheError(#[from] crate::groups_v2::CredentialsCacheError),
89
90 #[error("groups v2 (zero-knowledge) error")]
91 GroupsV2Error,
92
93 #[error(transparent)]
94 GroupsV2DecryptionError(#[from] GroupDecodingError),
95
96 #[error(transparent)]
97 ZkGroupDeserializationFailure(#[from] ZkGroupDeserializationFailure),
98
99 #[error(transparent)]
100 ZkGroupVerificationFailure(#[from] ZkGroupVerificationFailure),
101
102 #[error("unsupported content")]
103 UnsupportedContent,
104
105 #[error("Not found.")]
106 NotFoundError,
107
108 #[error("failed to decrypt field from device info: {0}")]
109 DecryptDeviceInfoFieldError(&'static str),
110
111 #[error("Unknown CDN version {0}")]
112 UnknownCdnVersion(u32),
113
114 #[error("Device limit reached: {current} out of {max} devices.")]
115 DeviceLimitReached { current: u32, max: u32 },
116
117 #[error("HTTP reqwest error: {0}")]
118 Http(#[from] reqwest::Error),
119
120 #[error(transparent)]
121 Curve(#[from] CurveError),
122
123 #[error("Cryptographic error: {0}")]
126 Hpke(signal_crypto::HpkeError),
127
128 #[error("Fingerprint error: {0}")]
131 Fingerprint(FingerprintError),
132
133 #[error("CDSI lookup error: {0}")]
134 #[cfg(feature = "cdsi")]
135 CdsiLookupError(#[from] libsignal_net::cdsi::LookupError),
136}
137
138impl From<signal_crypto::HpkeError> for ServiceError {
139 fn from(value: signal_crypto::HpkeError) -> Self {
140 ServiceError::Hpke(value)
141 }
142}
143
144impl From<FingerprintError> for ServiceError {
145 fn from(value: FingerprintError) -> Self {
146 ServiceError::Fingerprint(value)
147 }
148}
149
150impl From<reqwest_websocket::Error> for ServiceError {
151 fn from(error: reqwest_websocket::Error) -> Self {
152 Self::WsError(Box::new(error))
153 }
154}