use std::fmt;
#[derive(Debug)]
pub enum FetchError {
Request(wreq::Error),
Url(url::ParseError),
Json(serde_json::Error),
InvalidProxy(String),
SessionNotActive,
SessionAlreadyActive,
MaxRetriesExceeded {
attempts: u32,
last_error: Box<FetchError>,
},
NoRequest,
Other(String),
}
impl fmt::Display for FetchError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Request(e) => write!(f, "HTTP request error: {e}"),
Self::Url(e) => write!(f, "URL parse error: {e}"),
Self::Json(e) => write!(f, "JSON error: {e}"),
Self::InvalidProxy(msg) => write!(f, "invalid proxy: {msg}"),
Self::SessionNotActive => write!(f, "no active session"),
Self::SessionAlreadyActive => write!(f, "session already active"),
Self::MaxRetriesExceeded {
attempts,
last_error,
} => write!(f, "failed after {attempts} attempts: {last_error}"),
Self::NoRequest => write!(f, "response has no associated request (not from a spider)"),
Self::Other(msg) => write!(f, "{msg}"),
}
}
}
impl std::error::Error for FetchError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::Request(e) => Some(e),
Self::Url(e) => Some(e),
Self::Json(e) => Some(e),
Self::MaxRetriesExceeded { last_error, .. } => Some(last_error.as_ref()),
_ => None,
}
}
}
impl From<wreq::Error> for FetchError {
fn from(e: wreq::Error) -> Self {
Self::Request(e)
}
}
impl From<url::ParseError> for FetchError {
fn from(e: url::ParseError) -> Self {
Self::Url(e)
}
}
impl From<serde_json::Error> for FetchError {
fn from(e: serde_json::Error) -> Self {
Self::Json(e)
}
}
pub type Result<T> = std::result::Result<T, FetchError>;