1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3use thiserror::Error;
4use ureq::{Response, Transport};
5
6#[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}