use interrupt_support::Interrupted;
#[cfg(feature = "sync-client")]
#[derive(Debug, Clone)]
pub enum ErrorResponse {
NotFound { route: String },
Unauthorized { route: String },
PreconditionFailed { route: String },
ServerError { route: String, status: u16 }, 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),
#[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,
#[cfg(feature = "sync-client")]
#[error("Not all records were successfully uploaded")]
RecordUploadFailed,
#[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,
#[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
}
}
}