bitwarden_core/
error.rs

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