drogue_client/
error.rs

1//! Error and error information.
2
3use reqwest::StatusCode;
4use serde::{Deserialize, Serialize};
5use std::fmt;
6use url::ParseError;
7
8/// Additional error information.
9#[derive(Clone, Debug, Serialize, Deserialize)]
10pub struct ErrorInformation {
11    /// A machine processable error type.
12    pub error: String,
13    /// A human readable error message.
14    #[serde(default)]
15    pub message: String,
16}
17
18#[derive(thiserror::Error, Debug)]
19pub enum ClientError {
20    /// An error from the underlying API client (e.g. reqwest).
21    #[error("client error: {0}")]
22    Client(#[from] Box<dyn std::error::Error + Send + Sync>),
23    /// A local error, performing the request.
24    #[error("request error: {0}")]
25    Request(String),
26    /// A remote error, performing the request.
27    #[error("service error. HTTP {0}")]
28    Response(StatusCode),
29    /// The request was processed, but the response was unexpected.
30    #[error("unexpected response: {0}")]
31    UnexpectedResponse(String),
32    /// A remote error, performing the request, with additional details
33    #[error("service error. HTTP {code}. {error}")]
34    Service {
35        code: StatusCode,
36        error: ErrorInformation,
37    },
38    /// A token provider error.
39    #[error("token error: {0}")]
40    Token(#[source] Box<dyn std::error::Error + Send + Sync>),
41    /// Url error.
42    #[error("Url parse error")]
43    Url(#[from] ParseError),
44    /// Syntax error.
45    #[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}