diff options
Diffstat (limited to 'third_party/rust/sync15/src/error.rs')
-rw-r--r-- | third_party/rust/sync15/src/error.rs | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/third_party/rust/sync15/src/error.rs b/third_party/rust/sync15/src/error.rs new file mode 100644 index 0000000000..e4a043b8ac --- /dev/null +++ b/third_party/rust/sync15/src/error.rs @@ -0,0 +1,138 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use interrupt_support::Interrupted; + +/// This enum is to discriminate `StorageHttpError`, and not used as an error. +#[cfg(feature = "sync-client")] +#[derive(Debug, Clone)] +pub enum ErrorResponse { + NotFound { route: String }, + // 401 + Unauthorized { route: String }, + // 412 + PreconditionFailed { route: String }, + // 5XX + ServerError { route: String, status: u16 }, // TODO: info for "retry-after" and backoff handling etc here. + // Other HTTP responses. + RequestFailed { route: String, status: u16 }, +} + +pub type Result<T> = std::result::Result<T, Error>; + +#[derive(Debug, thiserror::Error)] +pub enum Error { + #[cfg(feature = "crypto")] + #[error("Key {0} had wrong length, got {1}, expected {2}")] + BadKeyLength(&'static str, usize, usize), + + #[cfg(feature = "crypto")] + #[error("SHA256 HMAC Mismatch error")] + HmacMismatch, + + #[cfg(feature = "crypto")] + #[error("Crypto/NSS error: {0}")] + CryptoError(#[from] rc_crypto::Error), + + #[cfg(feature = "crypto")] + #[error("Base64 decode error: {0}")] + Base64Decode(#[from] base64::DecodeError), + + #[error("JSON error: {0}")] + JsonError(#[from] serde_json::Error), + + #[error("Bad cleartext UTF8: {0}")] + BadCleartextUtf8(#[from] std::string::FromUtf8Error), + + #[cfg(feature = "crypto")] + #[error("HAWK error: {0}")] + HawkError(#[from] rc_crypto::hawk::Error), + + // + // Errors specific to this module. + // + #[cfg(feature = "sync-client")] + #[error("HTTP status {0} when requesting a token from the tokenserver")] + TokenserverHttpError(u16), + + #[cfg(feature = "sync-client")] + #[error("HTTP storage error: {0:?}")] + StorageHttpError(ErrorResponse), + + #[cfg(feature = "sync-client")] + #[error("Server requested backoff. Retry after {0:?}")] + BackoffError(std::time::SystemTime), + + #[cfg(feature = "sync-client")] + #[error("Outgoing record is too large to upload")] + RecordTooLargeError, + + // Do we want to record the concrete problems? + #[cfg(feature = "sync-client")] + #[error("Not all records were successfully uploaded")] + RecordUploadFailed, + + /// Used for things like a node reassignment or an unexpected syncId + /// implying the app needs to "reset" its understanding of remote storage. + #[cfg(feature = "sync-client")] + #[error("The server has reset the storage for this account")] + StorageResetError, + + #[cfg(feature = "sync-client")] + #[error("Unacceptable URL: {0}")] + UnacceptableUrl(String), + + #[cfg(feature = "sync-client")] + #[error("Missing server timestamp header in request")] + MissingServerTimestamp, + + #[cfg(feature = "sync-client")] + #[error("Unexpected server behavior during batch upload: {0}")] + ServerBatchProblem(&'static str), + + #[cfg(feature = "sync-client")] + #[error("It appears some other client is also trying to setup storage; try again later")] + SetupRace, + + #[cfg(feature = "sync-client")] + #[error("Client upgrade required; server storage version too new")] + ClientUpgradeRequired, + + // This means that our global state machine needs to enter a state (such as + // "FreshStartNeeded", but the allowed_states don't include that state.) + // It typically means we are trying to do a "fast" or "read-only" sync. + #[cfg(feature = "sync-client")] + #[error("Our storage needs setting up and we can't currently do it")] + SetupRequired, + + #[cfg(feature = "sync-client")] + #[error("Store error: {0}")] + StoreError(#[from] anyhow::Error), + + #[cfg(feature = "sync-client")] + #[error("Network error: {0}")] + RequestError(#[from] viaduct::Error), + + #[cfg(feature = "sync-client")] + #[error("Unexpected HTTP status: {0}")] + UnexpectedStatus(#[from] viaduct::UnexpectedStatus), + + #[cfg(feature = "sync-client")] + #[error("URL parse error: {0}")] + MalformedUrl(#[from] url::ParseError), + + #[error("The operation was interrupted.")] + Interrupted(#[from] Interrupted), +} + +#[cfg(feature = "sync-client")] +impl Error { + pub(crate) fn get_backoff(&self) -> Option<std::time::SystemTime> { + if let Error::BackoffError(time) = self { + Some(*time) + } else { + None + } + } +} |