push/
error.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5use error_support::{ErrorHandling, GetErrorHandling};
6// reexport logging helpers.
7pub use error_support::{debug, error, info, warn};
8
9pub type Result<T, E = PushError> = std::result::Result<T, E>;
10
11pub type ApiResult<T, E = PushApiError> = std::result::Result<T, E>;
12
13#[derive(Debug, thiserror::Error)]
14pub enum PushApiError {
15    /// The UAID was not recognized by the server
16    #[error("Unrecognized UAID: {0}")]
17    UAIDNotRecognizedError(String),
18
19    /// Record not found for the given chid
20    #[error("No record for chid {0}")]
21    RecordNotFoundError(String),
22
23    /// Internal Error
24    #[error("Internal Error: {0}")]
25    InternalError(String),
26}
27
28#[derive(Debug, thiserror::Error)]
29pub enum PushError {
30    /// An unspecified general error has occurred
31    #[error("General Error: {0:?}")]
32    GeneralError(String),
33
34    #[error("Crypto error: {0}")]
35    CryptoError(String),
36
37    /// A Client communication error
38    #[error("Communication Error: {0:?}")]
39    CommunicationError(String),
40
41    /// An error returned from the registration Server
42    #[error("Communication Server Error: {0}")]
43    CommunicationServerError(String),
44
45    /// Channel is already registered, generate new channelID
46    #[error("Channel already registered.")]
47    AlreadyRegisteredError,
48
49    /// An error with Storage
50    #[error("Storage Error: {0:?}")]
51    StorageError(String),
52
53    #[error("No record for chid {0:?}")]
54    RecordNotFoundError(String),
55
56    /// A failure to encode data to/from storage.
57    #[error("Error executing SQL: {0}")]
58    StorageSqlError(#[from] rusqlite::Error),
59
60    #[error("Transcoding Error: {0}")]
61    TranscodingError(String),
62
63    /// A failure to parse a URL.
64    #[error("URL parse error: {0:?}")]
65    UrlParseError(#[from] url::ParseError),
66
67    /// A failure deserializing json.
68    #[error("Failed to parse json: {0}")]
69    JSONDeserializeError(#[from] serde_json::Error),
70
71    /// The UAID was not recognized by the server
72    #[error("Unrecognized UAID: {0}")]
73    UAIDNotRecognizedError(String),
74
75    /// Was unable to send request to server
76    #[error("Unable to send request to server: {0}")]
77    RequestError(#[from] viaduct::Error),
78
79    /// Was unable to open the database
80    #[error("Error opening database: {0}")]
81    OpenDatabaseError(#[from] sql_support::open_database::Error),
82}
83
84impl From<bincode::Error> for PushError {
85    fn from(value: bincode::Error) -> Self {
86        PushError::TranscodingError(format!("bincode error: {value}"))
87    }
88}
89
90impl From<base64::DecodeError> for PushError {
91    fn from(value: base64::DecodeError) -> Self {
92        PushError::TranscodingError(format!("base64 error: {value}"))
93    }
94}
95
96impl From<rc_crypto::ece::Error> for PushError {
97    fn from(value: rc_crypto::ece::Error) -> Self {
98        PushError::CryptoError(value.to_string())
99    }
100}
101
102impl GetErrorHandling for PushError {
103    type ExternalError = PushApiError;
104
105    fn get_error_handling(&self) -> error_support::ErrorHandling<Self::ExternalError> {
106        match self {
107            Self::UAIDNotRecognizedError(s) => {
108                ErrorHandling::convert(PushApiError::UAIDNotRecognizedError(s.clone()))
109                    .report_error("uaid-not-recognized")
110            }
111            Self::RecordNotFoundError(s) => {
112                ErrorHandling::convert(PushApiError::RecordNotFoundError(s.clone()))
113            }
114
115            _ => ErrorHandling::convert(PushApiError::InternalError(self.to_string())),
116        }
117    }
118}