bitwarden_core/
error.rs

1//! Errors that can occur when using this SDK
2
3use std::fmt::Debug;
4
5use bitwarden_api_base::Error as BaseApiError;
6#[cfg(feature = "internal")]
7use bitwarden_error::bitwarden_error;
8use reqwest::StatusCode;
9use thiserror::Error;
10
11/// Errors from performing network requests.
12#[allow(missing_docs)]
13#[derive(Debug, Error)]
14#[cfg_attr(feature = "uniffi", derive(uniffi::Error), uniffi(flat_error))]
15pub enum ApiError {
16    #[error(transparent)]
17    Reqwest(#[from] reqwest::Error),
18    #[error(transparent)]
19    ReqwestMiddleware(#[from] reqwest_middleware::Error),
20    #[error(transparent)]
21    Serde(#[from] serde_json::Error),
22    #[error(transparent)]
23    Io(#[from] std::io::Error),
24
25    #[error("Received error message from server: [{}] {}", .status, .message)]
26    ResponseContent { status: StatusCode, message: String },
27}
28
29impl<T> From<BaseApiError<T>> for ApiError {
30    fn from(e: BaseApiError<T>) -> Self {
31        match e {
32            BaseApiError::Reqwest(e) => Self::Reqwest(e),
33            BaseApiError::ReqwestMiddleware(e) => Self::ReqwestMiddleware(e),
34            BaseApiError::ResponseError(e) => Self::ResponseContent {
35                status: e.status,
36                message: e.content,
37            },
38            BaseApiError::Serde(e) => Self::Serde(e),
39            BaseApiError::Io(e) => Self::Io(e),
40        }
41    }
42}
43
44/// Client is not authenticated or the session has expired.
45#[derive(Debug, Error)]
46#[error("The client is not authenticated or the session has expired")]
47pub struct NotAuthenticatedError;
48
49/// Client's user ID is already set.
50#[derive(Debug, Error, serde::Serialize, serde::Deserialize, Clone)]
51#[error("The client user ID is already set")]
52pub struct UserIdAlreadySetError;
53
54/// Missing required field.
55#[derive(Debug, Error)]
56#[error("The response received was missing a required field: {0}")]
57pub struct MissingFieldError(pub &'static str);
58
59/// Wrong password.
60#[derive(Debug, thiserror::Error)]
61#[error("Wrong password")]
62pub struct WrongPasswordError;
63
64/// Missing private key.
65#[derive(Debug, thiserror::Error)]
66#[error("Missing private key")]
67pub struct MissingPrivateKeyError;
68
69/// Signifies that the state is invalid from a cryptographic perspective, such as a required
70/// security value missing, or being invalid
71#[cfg(feature = "internal")]
72#[bitwarden_error(flat)]
73#[derive(Debug, thiserror::Error)]
74pub enum StatefulCryptoError {
75    /// The security state is not present, but required for this user. V2 users must always
76    /// have a security state, V1 users cannot have a security state.
77    #[error("Security state is required, but missing")]
78    MissingSecurityState,
79    /// The function expected a user in a account cryptography version, but got a different one.
80    #[error("Expected user in account cryptography version {expected}, but got {got}")]
81    WrongAccountCryptoVersion {
82        /// The expected account cryptography version. This can include a range, such as `2+`.
83        expected: String,
84        /// The actual account cryptography version.
85        got: u32,
86    },
87    #[error("Crypto error, {0}")]
88    Crypto(#[from] bitwarden_crypto::CryptoError),
89}
90
91/// This macro is used to require that a value is present or return an error otherwise.
92/// It is equivalent to using `val.ok_or(Error::MissingFields)?`, but easier to use and
93/// with a more descriptive error message.
94/// Note that this macro will return early from the function if the value is not present.
95#[macro_export]
96macro_rules! require {
97    ($val:expr) => {
98        match $val {
99            Some(val) => val,
100            None => return Err($crate::MissingFieldError(stringify!($val)).into()),
101        }
102    };
103}