1use std::{error::Error as StdError, fmt, time::Duration};
2
3use reqwest::StatusCode;
4
5#[derive(Debug)]
6pub enum Error {
7 InvalidBaseUrl(String),
8 InvalidHeader(String),
9 Http(reqwest::Error),
10 Serialization(serde_json::Error),
11 HttpStatus {
12 status: StatusCode,
13 api_error: Option<String>,
14 body: String,
15 },
16 AuthenticationRequired,
17 RefreshFailed {
18 status: Option<StatusCode>,
19 message: String,
20 },
21 UrlJoin {
22 path: String,
23 source: url::ParseError,
24 },
25 InvalidTimeout(Duration),
26}
27
28impl fmt::Display for Error {
29 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
30 match self {
31 Self::InvalidBaseUrl(url) => write!(f, "invalid base url: {url}"),
32 Self::InvalidHeader(value) => write!(f, "invalid header value: {value}"),
33 Self::Http(error) => write!(f, "{error}"),
34 Self::Serialization(error) => write!(f, "{error}"),
35 Self::HttpStatus {
36 status,
37 api_error,
38 body,
39 } => {
40 if let Some(error) = api_error {
41 write!(f, "http {status}: {error}")
42 } else {
43 write!(f, "http {status}: {body}")
44 }
45 }
46 Self::AuthenticationRequired => {
47 write!(f, "authentication required before calling this API")
48 }
49 Self::RefreshFailed { status, message } => match status {
50 Some(status) => write!(f, "token refresh failed with {status}: {message}"),
51 None => write!(f, "token refresh failed: {message}"),
52 },
53 Self::UrlJoin { path, source } => {
54 write!(f, "failed to resolve path '{path}': {source}")
55 }
56 Self::InvalidTimeout(timeout) => {
57 write!(f, "invalid timeout: {:?}", timeout)
58 }
59 }
60 }
61}
62
63impl StdError for Error {
64 fn source(&self) -> Option<&(dyn StdError + 'static)> {
65 match self {
66 Self::Http(error) => Some(error),
67 Self::Serialization(error) => Some(error),
68 Self::UrlJoin { source, .. } => Some(source),
69 _ => None,
70 }
71 }
72}
73
74impl From<reqwest::Error> for Error {
75 fn from(value: reqwest::Error) -> Self {
76 Self::Http(value)
77 }
78}
79
80impl From<serde_json::Error> for Error {
81 fn from(value: serde_json::Error) -> Self {
82 Self::Serialization(value)
83 }
84}