Skip to main content

bitwarden_api_base/
error.rs

1//! Error types for API operations.
2
3use std::{error, fmt};
4
5use serde::{Deserialize, Serialize};
6
7/// Response content from a failed API call.
8#[derive(Debug, Serialize, Deserialize)]
9#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
10pub struct ResponseContent {
11    /// HTTP status code of the response.
12    #[serde(with = "crate::status_code_serializer")]
13    pub status: reqwest::StatusCode,
14    /// Response body content.
15    pub message: String,
16}
17
18/// Errors that can occur during API operations.
19#[derive(Debug)]
20#[cfg_attr(feature = "uniffi", derive(uniffi::Error), uniffi(flat_error))]
21pub enum ApiError {
22    /// Error from the reqwest HTTP client.
23    Reqwest(reqwest::Error),
24    /// Error from the reqwest middleware.
25    ReqwestMiddleware(reqwest_middleware::Error),
26    /// JSON serialization/deserialization error.
27    Serde(serde_json::Error),
28    /// I/O error.
29    Io(std::io::Error),
30    /// API returned an error response.
31    Response(ResponseContent),
32}
33
34/// Error alias for backwards compatibility, prefer `ApiError` instead.
35pub type Error = ApiError;
36
37impl fmt::Display for ApiError {
38    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39        let (module, e) = match self {
40            Error::Reqwest(e) => ("reqwest", e.to_string()),
41            Error::ReqwestMiddleware(e) => ("reqwest-middleware", e.to_string()),
42            Error::Serde(e) => ("serde", e.to_string()),
43            Error::Io(e) => ("IO", e.to_string()),
44            Error::Response(e) => (
45                "response",
46                format!("status code {}: {}", e.status, e.message),
47            ),
48        };
49        write!(f, "error in {}: {}", module, e)
50    }
51}
52
53impl error::Error for ApiError {
54    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
55        Some(match self {
56            Error::Reqwest(e) => e,
57            Error::ReqwestMiddleware(e) => e,
58            Error::Serde(e) => e,
59            Error::Io(e) => e,
60            Error::Response(_) => return None,
61        })
62    }
63}
64
65impl From<reqwest::Error> for ApiError {
66    fn from(e: reqwest::Error) -> Self {
67        Self::Reqwest(e)
68    }
69}
70
71impl From<reqwest_middleware::Error> for ApiError {
72    fn from(e: reqwest_middleware::Error) -> Self {
73        Self::ReqwestMiddleware(e)
74    }
75}
76
77impl From<serde_json::Error> for ApiError {
78    fn from(e: serde_json::Error) -> Self {
79        Self::Serde(e)
80    }
81}
82
83impl From<std::io::Error> for ApiError {
84    fn from(e: std::io::Error) -> Self {
85        Self::Io(e)
86    }
87}
88
89impl From<ResponseContent> for ApiError {
90    fn from(value: ResponseContent) -> Self {
91        Self::Response(value)
92    }
93}