uber_api/errors/
errors.rs

1use std::string::ToString;
2
3use thiserror::Error;
4
5// pub(crate) type UberResult<T> = Result<T, UberError>;
6
7pub trait UnwrapRequestField<T> {
8    fn unwrap_request_field(self, field_name: &str) -> Result<T, UberError>;
9}
10
11impl<T> UnwrapRequestField<T> for Option<T> {
12    fn unwrap_request_field(self, field_name: &str) -> Result<T, UberError> {
13        match self {
14            Some(t) => Ok(t),
15            None => Err(UberError::BadInput(format!(
16                "Request missing field '{}'",
17                field_name
18            ))),
19        }
20    }
21}
22
23/// Error enum for all cases of internal/external errors occurring during client execution
24#[derive(Error, Debug)]
25pub enum UberError {
26    // Http-like errors
27    #[error("Bad input - {0}")]
28    BadInput(String),
29    #[error("Unauthorized - {0}")]
30    Unauthorized(String),
31    #[error("Forbidden - {0}")]
32    Forbidden(String),
33    #[error("Invalid state - {0}")]
34    InvalidState(String),
35    #[error("Not found - {0}")]
36    NotFound(String),
37    #[error("Internal server error - {0}")]
38    InternalServerError(String),
39    #[error("Exists - {0}")]
40    Exists(String),
41    #[error("Not implemented - {0}")]
42    NotImplemented(String),
43    #[error("Timed out - {0}")]
44    Timeout(String),
45    #[error("invalid header (expected {expected:?}, found {found:?})")]
46    InvalidRequest { expected: String, found: String },
47
48    // Errors converted from others
49    #[error("Json error - {0:?}")]
50    JsonError(#[from] serde_json::Error),
51    #[error("Urlencoded error - {0:?}")]
52    UrlencodedError(#[from] serde_urlencoded::ser::Error),
53    #[error("ReqwestError - {0:?}")]
54    ReqwestError(#[from] reqwest::Error),
55    #[error("HeaderValue conversion error - {0:?}")]
56    HeaderValueError(#[from] reqwest::header::InvalidHeaderValue),
57    #[error("ParseError - {0:?}")]
58    ParseError(#[from] chrono::ParseError),
59    #[error(transparent)]
60    Other(#[from] anyhow::Error),
61}
62
63pub const UNAUTHORIZED: &str = "unauthorized";
64pub const FORBIDDEN: &str = "forbidden";
65pub const INVALID_INPUT: &str = "invalid-input";
66pub const INVALID_STATE: &str = "invalid-state";
67pub const NOT_FOUND: &str = "not-found";
68pub const INTERNAL_SERVER_ERROR: &str = "internal-server-error";
69pub const EXISTS: &str = "exists";
70pub const NOT_IMPLEMENTED: &str = "not-implemented";
71
72impl UberError {
73    pub fn from_code<T: Into<String>>(code: &str, message: T) -> Self {
74        match code {
75            UNAUTHORIZED => Self::Unauthorized(message.into()),
76            FORBIDDEN => Self::Forbidden(message.into()),
77            INVALID_INPUT => Self::BadInput(message.into()),
78            NOT_FOUND => Self::NotFound(message.into()),
79            INVALID_STATE => Self::InvalidState(message.into()),
80            INTERNAL_SERVER_ERROR => Self::InternalServerError(message.into()),
81            EXISTS => Self::Exists(message.into()),
82            NOT_IMPLEMENTED => Self::NotImplemented(message.into()),
83            _ => Self::InternalServerError(message.into()),
84        }
85    }
86
87    pub fn get_code(&self) -> String {
88        match self {
89            Self::Unauthorized(_) => UNAUTHORIZED.to_string(),
90            Self::Forbidden(_) => FORBIDDEN.to_string(),
91            Self::BadInput(_) => INVALID_INPUT.to_string(),
92            Self::InvalidState(_) => INVALID_STATE.to_string(),
93            Self::NotFound(_) => NOT_FOUND.to_string(),
94            Self::InternalServerError(_) => INTERNAL_SERVER_ERROR.to_string(),
95            Self::Exists(_) => EXISTS.to_string(),
96            Self::NotImplemented(_) => NOT_IMPLEMENTED.to_string(),
97            _ => INTERNAL_SERVER_ERROR.to_string(),
98        }
99    }
100}
101