use serde::{Deserialize, Serialize};
use serde_json::Value;
use thiserror::Error;
use ureq::{Response, Transport};
#[derive(Error, Deserialize, Serialize, Debug, PartialEq, Eq)]
pub enum DNSimpleError {
#[error("Authentication failed")]
Unauthorized,
#[error("Bad Gateway")]
BadGateway,
#[error("{message}")]
BadRequest {
message: String,
attribute_errors: Option<Value>,
},
#[error("{0}")]
GatewayTimeout(String),
#[error("Method not Allowed")]
MethodNotAllowed,
#[error("{0}")]
NotFound(String),
#[error("Your account is not subscribed or not in good standing")]
PaymentRequired,
#[error("{0}")]
PreconditionRequired(String),
#[error("Service Unavailable")]
ServiceUnavailable,
#[error("You exceeded the allowed number of requests per hour and your request has temporarily been throttled.")]
TooManyRequests,
#[error("Transport Error - {0}({1})")]
Transport(String, String),
#[error("Deserialization Error {0}")]
Deserialization(String),
}
impl DNSimpleError {
pub fn parse_response(code: u16, response: Response) -> DNSimpleError {
match code {
400 => Self::bad_request(response),
401 => Self::Unauthorized,
402 => Self::PaymentRequired,
404 => Self::not_found(response),
405 => Self::MethodNotAllowed,
428 => Self::precondition_required(response),
429 => Self::TooManyRequests,
502 => Self::BadGateway,
503 => Self::ServiceUnavailable,
504 => Self::gateway_timeout(response),
_ => Self::Transport(
response.status().to_string(),
response.status_text().to_string(),
),
}
}
pub fn parse_transport(transport: Transport) -> DNSimpleError {
Self::Transport(transport.to_string(), transport.kind().to_string())
}
fn bad_request(response: Response) -> DNSimpleError {
match Self::response_to_json(response) {
Ok(json) => Self::BadRequest {
message: Self::message_in(&json),
attribute_errors: Some(json["errors"].clone()),
},
Err(error) => error,
}
}
fn gateway_timeout(response: Response) -> DNSimpleError {
match Self::response_to_json(response) {
Ok(json) => Self::GatewayTimeout(Self::message_in(&json)),
Err(error) => error,
}
}
fn not_found(response: Response) -> DNSimpleError {
match Self::response_to_json(response) {
Ok(json) => Self::NotFound(Self::message_in(&json)),
Err(error) => error,
}
}
fn precondition_required(response: Response) -> DNSimpleError {
match Self::response_to_json(response) {
Ok(json) => Self::PreconditionRequired(Self::message_in(&json)),
Err(error) => error,
}
}
fn message_in(json: &Value) -> String {
match json["message"].as_str() {
None => String::from("Unable to parse error message"),
Some(json_string) => json_string.to_string(),
}
}
fn response_to_json(response: Response) -> Result<Value, DNSimpleError> {
match response.into_json::<Value>() {
Ok(value) => Ok(value),
Err(error) => Err(DNSimpleError::Deserialization(error.to_string())),
}
}
}