1use std::{error::Error, fmt::Display, num::ParseIntError};
2
3use http::StatusCode;
4
5#[derive(Debug)]
6pub enum ClientError {
7 RequestOrMiddlewareError(reqwest_middleware::Error),
8 RequestError(reqwest::Error),
9 Other(anyhow::Error),
10}
11
12impl From<anyhow::Error> for ClientError {
13 fn from(e: anyhow::Error) -> Self {
14 Self::Other(e)
15 }
16}
17
18impl From<reqwest_middleware::Error> for ClientError {
19 fn from(e: reqwest_middleware::Error) -> Self {
20 Self::RequestOrMiddlewareError(e)
21 }
22}
23
24impl From<reqwest::Error> for ClientError {
25 fn from(e: reqwest::Error) -> Self {
26 Self::RequestError(e)
27 }
28}
29
30impl From<ParseIntError> for ClientError {
31 fn from(e: ParseIntError) -> Self {
32 Self::Other(e.into())
33 }
34}
35
36impl ClientError {
37 pub fn status(&self) -> Option<StatusCode> {
38 match self {
39 ClientError::RequestOrMiddlewareError(e) => match e {
40 reqwest_middleware::Error::Middleware(_) => None,
41 reqwest_middleware::Error::Reqwest(e) => e.status(),
42 },
43 ClientError::RequestError(e) => e.status(),
44 ClientError::Other(_) => None,
45 }
46 }
47}
48
49impl Error for ClientError {
50 fn source(&self) -> Option<&(dyn Error + 'static)> {
51 match self {
52 ClientError::RequestOrMiddlewareError(e) => Some(e),
53 ClientError::RequestError(e) => Some(e),
54 ClientError::Other(e) => e.source(),
55 }
56 }
57
58 fn description(&self) -> &str {
59 "description() is deprecated; use Display"
60 }
61
62 fn cause(&self) -> Option<&dyn Error> {
63 self.source()
64 }
65}
66
67impl Display for ClientError {
68 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
69 match self {
70 ClientError::RequestOrMiddlewareError(e) => e.fmt(f),
71 ClientError::RequestError(e) => e.fmt(f),
72 ClientError::Other(e) => e.fmt(f),
73 }
74 }
75}