graph_error/
graph_failure.rs

1use crate::download::AsyncDownloadError;
2use crate::internal::GraphRsError;
3use crate::{AuthExecutionError, AuthorizationFailure, ErrorMessage};
4use reqwest::header::HeaderMap;
5use std::cell::BorrowMutError;
6use std::error::Error;
7use std::io;
8use std::io::ErrorKind;
9use std::num::ParseIntError;
10use std::str::Utf8Error;
11use std::sync::mpsc;
12
13#[derive(Debug, thiserror::Error)]
14#[allow(clippy::large_enum_variant)]
15#[non_exhaustive]
16pub enum GraphFailure {
17    #[error("{0:#?}")]
18    Io(#[from] io::Error),
19
20    #[error("{0:#?}")]
21    Utf8Error(#[from] Utf8Error),
22
23    #[error("{0:#?}")]
24    ReqwestError(#[from] reqwest::Error),
25
26    #[error("{0:#?}")]
27    SerdeJson(#[from] serde_json::Error),
28
29    #[error("{0:#?}")]
30    DecodeError(#[from] base64::DecodeError),
31
32    #[error("{0:#?}")]
33    RecvError(#[from] mpsc::RecvError),
34
35    #[error("{0:#?}")]
36    BorrowMutError(#[from] BorrowMutError),
37
38    #[error("{0:#?}")]
39    UrlParse(#[from] url::ParseError),
40
41    #[error("{0:#?}")]
42    HttpError(#[from] http::Error),
43
44    #[error("{0:#?}")]
45    GraphRsError(#[from] GraphRsError),
46
47    #[error("{0:#?}")]
48    HandlebarsRenderError(#[from] handlebars::RenderError),
49
50    #[error("{0:?}")]
51    HandlebarsTemplateRenderError(#[from] handlebars::TemplateRenderError),
52
53    #[error("Crypto Error (Unknown)")]
54    CryptoError,
55
56    #[error("{0:#?}")]
57    AsyncDownloadError(#[from] AsyncDownloadError),
58
59    #[error(
60        "Error building or processing request prior to being sent:\n{0:#?}",
61        error
62    )]
63    PreFlightError {
64        url: Option<reqwest::Url>,
65        headers: Option<HeaderMap>,
66        error: Option<Box<GraphFailure>>,
67        message: String,
68    },
69
70    #[error("{0:#?}", message)]
71    Default {
72        url: Option<reqwest::Url>,
73        headers: Option<HeaderMap>,
74        message: String,
75    },
76
77    #[error("{0:#?}")]
78    ErrorMessage(#[from] ErrorMessage),
79
80    #[error("Temporary Graph API Error")]
81    TemporaryError,
82
83    #[error("Parse Int error:\n{0:#?}")]
84    ParseIntError(#[from] ParseIntError),
85
86    #[error("message: {0:#?}, response: {1:#?}", message, response)]
87    SilentTokenAuth {
88        message: String,
89        response: http::Response<Result<serde_json::Value, ErrorMessage>>,
90    },
91
92    #[error("{0:#?}")]
93    JsonWebToken(#[from] jsonwebtoken::errors::Error),
94
95    #[error("{0:#?}")]
96    Other(#[from] Box<dyn Error + Send + Sync>),
97}
98
99impl GraphFailure {
100    pub fn error_kind(error_kind: io::ErrorKind, message: &str) -> Self {
101        let e = io::Error::new(error_kind, message);
102        GraphFailure::from(e)
103    }
104
105    pub fn internal(err: GraphRsError) -> GraphFailure {
106        GraphFailure::GraphRsError(err)
107    }
108
109    pub fn not_found(msg: &str) -> GraphFailure {
110        GraphFailure::error_kind(ErrorKind::NotFound, msg)
111    }
112
113    pub fn invalid(msg: &str) -> Self {
114        GraphFailure::internal(GraphRsError::InvalidOrMissing { msg: msg.into() })
115    }
116}
117
118impl Default for GraphFailure {
119    fn default() -> Self {
120        GraphFailure::Default {
121            url: None,
122            headers: None,
123            message: "Unknown Error".into(),
124        }
125    }
126}
127
128impl From<ring::error::Unspecified> for GraphFailure {
129    fn from(_: ring::error::Unspecified) -> Self {
130        GraphFailure::CryptoError
131    }
132}
133
134impl From<AuthExecutionError> for GraphFailure {
135    fn from(value: AuthExecutionError) -> Self {
136        match value {
137            AuthExecutionError::Authorization(authorization_failure) => match authorization_failure
138            {
139                AuthorizationFailure::RequiredValue { name, message } => {
140                    GraphFailure::PreFlightError {
141                        url: None,
142                        headers: None,
143                        error: None,
144                        message: format!("name: {:#?}, message: {:#?}", name, message),
145                    }
146                }
147                AuthorizationFailure::UrlParse(error) => GraphFailure::UrlParse(error),
148                AuthorizationFailure::Uuid(error) => GraphFailure::PreFlightError {
149                    url: None,
150                    headers: None,
151                    error: None,
152                    message: format!(
153                        "name: client_id, message: {:#?}, source: {:#?}",
154                        "Client Id is not a valid Uuid",
155                        error.to_string()
156                    ),
157                },
158                AuthorizationFailure::Openssl(message) => GraphFailure::PreFlightError {
159                    url: None,
160                    headers: None,
161                    error: None,
162                    message,
163                },
164                AuthorizationFailure::SerdeJson(error) => GraphFailure::SerdeJson(error),
165            },
166            AuthExecutionError::Request(e) => GraphFailure::ReqwestError(e),
167            AuthExecutionError::Http(e) => GraphFailure::HttpError(e),
168            AuthExecutionError::SilentTokenAuth { message, response } => {
169                GraphFailure::SilentTokenAuth { message, response }
170            }
171            AuthExecutionError::JsonWebToken(error) => GraphFailure::JsonWebToken(error),
172            AuthExecutionError::Other(e) => GraphFailure::Other(e),
173        }
174    }
175}