use url::Url;
use super::ReqwestErrorPhase;
use crate::{HttpError, HttpErrorKind};
pub(crate) fn map_reqwest_error(
error: reqwest::Error,
default_kind: HttpErrorKind,
phase: Option<ReqwestErrorPhase>,
method: Option<http::Method>,
url: Option<Url>,
) -> HttpError {
let kind = classify_reqwest_error_kind(
error.is_timeout(),
error.is_decode(),
error.is_status(),
error.is_request() && error.url().is_none(),
error.is_connect(),
phase,
default_kind,
);
let mut result = HttpError::new(kind, format!("HTTP transport error: {}", error));
if let Some(method) = method {
result = result.with_method(&method);
}
if let Some(url) = url {
result = result.with_url(&url);
}
result.with_source(error)
}
fn classify_reqwest_error_kind(
is_timeout: bool,
is_decode: bool,
is_status: bool,
is_request_without_url: bool,
is_connect: bool,
phase: Option<ReqwestErrorPhase>,
default_kind: HttpErrorKind,
) -> HttpErrorKind {
if is_timeout {
classify_timeout_kind(is_connect, phase)
} else if is_decode {
HttpErrorKind::Decode
} else if is_status {
HttpErrorKind::Status
} else if is_request_without_url {
HttpErrorKind::InvalidUrl
} else {
default_kind
}
}
fn classify_timeout_kind(is_connect: bool, phase: Option<ReqwestErrorPhase>) -> HttpErrorKind {
match phase {
Some(ReqwestErrorPhase::Send) => {
if is_connect {
HttpErrorKind::ConnectTimeout
} else {
HttpErrorKind::RequestTimeout
}
}
Some(ReqwestErrorPhase::Read) => HttpErrorKind::ReadTimeout,
None => HttpErrorKind::RequestTimeout,
}
}
#[cfg(coverage)]
#[doc(hidden)]
pub(crate) fn coverage_classify_timeout_kind(
is_connect: bool,
phase: Option<ReqwestErrorPhase>,
) -> HttpErrorKind {
classify_timeout_kind(is_connect, phase)
}
#[cfg(coverage)]
#[doc(hidden)]
pub(crate) fn coverage_classify_reqwest_error_kind(
is_timeout: bool,
is_decode: bool,
is_status: bool,
is_request_without_url: bool,
is_connect: bool,
phase: Option<ReqwestErrorPhase>,
default_kind: HttpErrorKind,
) -> HttpErrorKind {
classify_reqwest_error_kind(
is_timeout,
is_decode,
is_status,
is_request_without_url,
is_connect,
phase,
default_kind,
)
}