Skip to main content

dnsimple/
errors.rs

1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3use thiserror::Error;
4use ureq::{Response, Transport};
5
6/// Represents the possible errors thrown while interacting with the DNSimple API
7#[derive(Error, Deserialize, Serialize, Debug, PartialEq, Eq)]
8pub enum DNSimpleError {
9    #[error("Authentication failed")]
10    Unauthorized,
11    #[error("Bad Gateway")]
12    BadGateway,
13    #[error("{message}")]
14    BadRequest {
15        message: String,
16        attribute_errors: Option<Value>,
17    },
18    #[error("{0}")]
19    GatewayTimeout(String),
20    #[error("Method not Allowed")]
21    MethodNotAllowed,
22    #[error("{0}")]
23    NotFound(String),
24    #[error("Your account is not subscribed or not in good standing")]
25    PaymentRequired,
26    #[error("{0}")]
27    PreconditionRequired(String),
28    #[error("Service Unavailable")]
29    ServiceUnavailable,
30    #[error("You exceeded the allowed number of requests per hour and your request has temporarily been throttled.")]
31    TooManyRequests,
32    #[error("Transport Error - {0}({1})")]
33    Transport(String, String),
34    #[error("Deserialization Error {0}")]
35    Deserialization(String),
36}
37
38impl DNSimpleError {
39    pub fn parse_response(code: u16, response: Response) -> DNSimpleError {
40        match code {
41            400 => Self::bad_request(response),
42            401 => Self::Unauthorized,
43            402 => Self::PaymentRequired,
44            404 => Self::not_found(response),
45            405 => Self::MethodNotAllowed,
46            428 => Self::precondition_required(response),
47            429 => Self::TooManyRequests,
48            502 => Self::BadGateway,
49            503 => Self::ServiceUnavailable,
50            504 => Self::gateway_timeout(response),
51            _ => Self::Transport(
52                response.status().to_string(),
53                response.status_text().to_string(),
54            ),
55        }
56    }
57
58    pub fn parse_transport(transport: Transport) -> DNSimpleError {
59        Self::Transport(transport.to_string(), transport.kind().to_string())
60    }
61
62    fn bad_request(response: Response) -> DNSimpleError {
63        match Self::response_to_json(response) {
64            Ok(json) => Self::BadRequest {
65                message: Self::message_in(&json),
66                attribute_errors: Some(json["errors"].clone()),
67            },
68            Err(error) => error,
69        }
70    }
71
72    fn gateway_timeout(response: Response) -> DNSimpleError {
73        match Self::response_to_json(response) {
74            Ok(json) => Self::GatewayTimeout(Self::message_in(&json)),
75            Err(error) => error,
76        }
77    }
78
79    fn not_found(response: Response) -> DNSimpleError {
80        match Self::response_to_json(response) {
81            Ok(json) => Self::NotFound(Self::message_in(&json)),
82            Err(error) => error,
83        }
84    }
85
86    fn precondition_required(response: Response) -> DNSimpleError {
87        match Self::response_to_json(response) {
88            Ok(json) => Self::PreconditionRequired(Self::message_in(&json)),
89            Err(error) => error,
90        }
91    }
92
93    fn message_in(json: &Value) -> String {
94        match json["message"].as_str() {
95            None => String::from("Unable to parse error message"),
96            Some(json_string) => json_string.to_string(),
97        }
98    }
99
100    fn response_to_json(response: Response) -> Result<Value, DNSimpleError> {
101        match response.into_json::<Value>() {
102            Ok(value) => Ok(value),
103            Err(error) => Err(DNSimpleError::Deserialization(error.to_string())),
104        }
105    }
106}