Skip to main content

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