1use reqwest::StatusCode;
4use serde::{Deserialize, Serialize};
5use std::fmt;
6use url::ParseError;
7
8#[derive(Clone, Debug, Serialize, Deserialize)]
10pub struct ErrorInformation {
11 pub error: String,
13 #[serde(default)]
15 pub message: String,
16}
17
18#[derive(thiserror::Error, Debug)]
19pub enum ClientError {
20 #[error("client error: {0}")]
22 Client(#[from] Box<dyn std::error::Error + Send + Sync>),
23 #[error("request error: {0}")]
25 Request(String),
26 #[error("service error. HTTP {0}")]
28 Response(StatusCode),
29 #[error("unexpected response: {0}")]
31 UnexpectedResponse(String),
32 #[error("service error. HTTP {code}. {error}")]
34 Service {
35 code: StatusCode,
36 error: ErrorInformation,
37 },
38 #[error("token error: {0}")]
40 Token(#[source] Box<dyn std::error::Error + Send + Sync>),
41 #[error("Url parse error")]
43 Url(#[from] ParseError),
44 #[error("Syntax error: {0}")]
46 Syntax(#[source] Box<dyn std::error::Error + Send + Sync>),
47}
48
49impl ClientError {
50 pub fn syntax<S>(err: S) -> ClientError
51 where
52 S: std::error::Error + Send + Sync + 'static,
53 {
54 Self::Syntax(Box::new(err))
55 }
56}
57
58#[cfg(feature = "reqwest")]
59impl From<reqwest::Error> for ClientError {
60 fn from(err: reqwest::Error) -> Self {
61 ClientError::Client(Box::new(err))
62 }
63}
64
65impl From<serde_json::Error> for ClientError {
66 fn from(err: serde_json::Error) -> Self {
67 ClientError::Syntax(Box::new(err))
68 }
69}
70
71impl fmt::Display for ErrorInformation {
72 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
73 if self.error.is_empty() {
74 write!(f, "{}", self.message)
75 } else {
76 write!(f, "{}: {}", self.error, self.message)
77 }
78 }
79}