diff --git a/Cargo.lock b/Cargo.lock index 302a0fa2f..55e20bef1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1022,6 +1022,7 @@ dependencies = [ "hardened_malloc-rs", "http", "http-body-util", + "hyper-util", "ipaddress", "itertools 0.14.0", "libc", diff --git a/Cargo.toml b/Cargo.toml index de28a23d9..8217542a2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -550,9 +550,6 @@ version = "0.12.0" default-features = false features = ["sync", "tls-rustls", "rustls-provider"] -[workspace.dependencies.resolv-conf] -version = "0.7.5" - [workspace.dependencies.yansi] version = "1.0.1" diff --git a/src/core/Cargo.toml b/src/core/Cargo.toml index 0b8b8692a..25498470b 100644 --- a/src/core/Cargo.toml +++ b/src/core/Cargo.toml @@ -114,6 +114,7 @@ tracing.workspace = true url.workspace = true parking_lot.workspace = true lock_api.workspace = true +hyper-util.workspace = true [target.'cfg(unix)'.dependencies] nix.workspace = true diff --git a/src/core/error/mod.rs b/src/core/error/mod.rs index e3f0437eb..2348ee271 100644 --- a/src/core/error/mod.rs +++ b/src/core/error/mod.rs @@ -4,7 +4,7 @@ mod panic; mod response; mod serde; -use std::{any::Any, borrow::Cow, convert::Infallible, sync::PoisonError}; +use std::{any::Any, borrow::Cow, convert::Infallible, error::Error as _, sync::PoisonError}; pub use self::{err::visit, log::*}; @@ -66,8 +66,8 @@ pub enum Error { Poison(Cow<'static, str>), #[error("Regex error: {0}")] Regex(#[from] regex::Error), - #[error("Request error: {0}")] - Reqwest(#[from] reqwest::Error), + #[error("{0}")] + Reqwest(FormattedReqwestError), #[error("{0}")] SerdeDe(Cow<'static, str>), #[error("{0}")] @@ -236,3 +236,48 @@ pub fn infallible(_e: &Infallible) { #[must_use] #[allow(clippy::needless_pass_by_value)] pub fn sanitized_message(e: Error) -> String { e.sanitized_message() } + +#[derive(Debug)] +pub struct FormattedReqwestError(reqwest::Error); + +impl std::ops::Deref for FormattedReqwestError { + type Target = reqwest::Error; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl std::error::Error for FormattedReqwestError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + self.0.source() + } +} + +impl std::fmt::Display for FormattedReqwestError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(hyper_error) = self.0.source() + && hyper_error.is::() + && let Some(real_error) = hyper_error.source() + { + if let Some(real_reason) = real_error.source() { + write!(f, "{}: {}", real_error, real_reason) + } else { + write!(f, "{}", real_error) + } + } else { + write!(f, "Request error: {}", &self.0) + } + } +} + +impl From for FormattedReqwestError { + fn from(err: reqwest::Error) -> Self { + FormattedReqwestError(err) + } +} + +impl From for Error { + fn from(err: reqwest::Error) -> Self { + Error::Reqwest(err.into()) + } +}