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    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("Error sending request: {reason}")]
27    SendError { reason: String },
28
29    #[error("i/o error")]
30    IO(#[from] std::io::Error),
31
32    #[error("Error decoding JSON: {0}")]
33    JsonDecodeError(#[from] serde_json::Error),
34    #[error("Error decoding protobuf frame: {0}")]
35    ProtobufDecodeError(#[from] prost::DecodeError),
36    #[error("error encoding or decoding bincode: {0}")]
37    BincodeError(#[from] bincode::Error),
38    #[error("error decoding base64 string: {0}")]
39    Base64DecodeError(#[from] base64::DecodeError),
40
41    #[error("Rate limit exceeded")]
42    RateLimitExceeded,
43    #[error("Authorization failed")]
44    Unauthorized,
45    #[error("Registration lock is set: {0:?}")]
46    Locked(RegistrationLockFailure),
47    #[error("Unexpected response: HTTP {http_code}")]
48    UnhandledResponseCode { http_code: u16 },
49
50    #[error("Websocket error: {0}")]
51    WsError(Box<reqwest_websocket::Error>),
52    #[error("Websocket closing: {reason}")]
53    WsClosing { reason: &'static str },
54
55    #[error("Invalid padding: {0}")]
56    Padding(#[from] UnpadError),
57
58    #[error("unknown padding version {0}")]
59    PaddingVersion(u32),
60
61    #[error("Invalid frame: {reason}")]
62    InvalidFrame { reason: &'static str },
63
64    #[error("MAC error")]
65    MacError,
66
67    #[error("Protocol error: {0}")]
68    SignalProtocolError(#[from] SignalProtocolError),
69
70    #[error("invalid device id: {0}")]
71    InvalidDeviceId(#[from] libsignal_core::InvalidDeviceId),
72
73    #[error("Proof required: {0:?}")]
74    ProofRequiredError(ProofRequired),
75
76    #[error("{0:?}")]
77    MismatchedDevicesException(MismatchedDevices),
78
79    #[error("{0:?}")]
80    StaleDevices(StaleDevices),
81
82    #[error(transparent)]
83    CredentialsCacheError(#[from] crate::groups_v2::CredentialsCacheError),
84
85    #[error("groups v2 (zero-knowledge) error")]
86    GroupsV2Error,
87
88    #[error(transparent)]
89    GroupsV2DecryptionError(#[from] GroupDecodingError),
90
91    #[error(transparent)]
92    ZkGroupDeserializationFailure(#[from] ZkGroupDeserializationFailure),
93
94    #[error(transparent)]
95    ZkGroupVerificationFailure(#[from] ZkGroupVerificationFailure),
96
97    #[error("unsupported content")]
98    UnsupportedContent,
99
100    #[error("Not found.")]
101    NotFoundError,
102
103    #[error("invalid device name")]
104    InvalidDeviceName,
105
106    #[error("Unknown CDN version {0}")]
107    UnknownCdnVersion(u32),
108
109    #[error("HTTP reqwest error: {0}")]
110    Http(#[from] reqwest::Error),
111
112    #[error(transparent)]
113    Curve(#[from] CurveError),
114
115    // FingerprintError does not implement StdError, so we need a manual display,
116    // and manual From impl.
117    #[error("Fingerprint error: {0}")]
118    Fingerprint(FingerprintError),
119}
120
121impl From<FingerprintError> for ServiceError {
122    fn from(value: FingerprintError) -> Self {
123        ServiceError::Fingerprint(value)
124    }
125}
126
127impl From<reqwest_websocket::Error> for ServiceError {
128    fn from(error: reqwest_websocket::Error) -> Self {
129        Self::WsError(Box::new(error))
130    }
131}