use std::fmt;
use std::io;
use reqwest::StatusCode;
#[derive(Debug)]
pub enum AppError {
Io(io::Error),
#[cfg(feature = "client")]
Json(serde_json::Error),
Http(reqwest::Error),
InvalidRequestConfig(String),
UpstreamResponse {
status: Option<StatusCode>,
message: String,
},
}
impl fmt::Display for AppError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Io(error) => write!(f, "{error}"),
#[cfg(feature = "client")]
Self::Json(error) => write!(f, "{error}"),
Self::Http(error) => write!(f, "{error}"),
Self::InvalidRequestConfig(message) => f.write_str(message),
Self::UpstreamResponse {
status: Some(status),
message,
} => write!(f, "upstream request failed with status {status}: {message}"),
Self::UpstreamResponse {
status: None,
message,
} => f.write_str(message),
}
}
}
impl std::error::Error for AppError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::Io(error) => Some(error),
#[cfg(feature = "client")]
Self::Json(error) => Some(error),
Self::Http(error) => Some(error),
Self::InvalidRequestConfig(_) | Self::UpstreamResponse { .. } => None,
}
}
}
impl From<io::Error> for AppError {
fn from(value: io::Error) -> Self {
Self::Io(value)
}
}
#[cfg(feature = "client")]
impl From<serde_json::Error> for AppError {
fn from(value: serde_json::Error) -> Self {
Self::Json(value)
}
}
impl From<reqwest::Error> for AppError {
fn from(value: reqwest::Error) -> Self {
Self::Http(value)
}
}