Skip to main content

context69_sdk/
error.rs

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