From ac0ac5f7f77fc84ec8f8d0aaf69c10318830f59d Mon Sep 17 00:00:00 2001 From: Shiven Garia Date: Wed, 11 Mar 2026 18:44:58 +0530 Subject: [PATCH] fix: Include full error chain in procedure HTTP request errors Walk the `source()` chain of `reqwest::Error` when converting to `NodesError::HttpError`, so users see the underlying cause (DNS failure, connection refused, timeout, TLS error, etc.) instead of just the opaque top-level "error sending request for url" message. Fixes #4608 --- crates/core/src/host/instance_env.rs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/crates/core/src/host/instance_env.rs b/crates/core/src/host/instance_env.rs index a47f035cf34..afda477eb58 100644 --- a/crates/core/src/host/instance_env.rs +++ b/crates/core/src/host/instance_env.rs @@ -857,8 +857,18 @@ impl InstanceEnv { err } - fn http_error(err: E) -> NodesError { - NodesError::HttpError(err.to_string()) + fn http_error(err: E) -> NodesError { + // Include the full error chain, not just the top-level message. + // `reqwest::Error` wraps underlying causes (DNS failure, connection refused, + // timeout, TLS errors, etc.) which are essential for debugging. + use std::fmt::Write; + let mut message = err.to_string(); + let mut source = err.source(); + while let Some(cause) = source { + write!(message, ": {cause}").unwrap(); + source = cause.source(); + } + NodesError::HttpError(message) } // Then convert the request into an `http::Request`, a semi-standard "lingua franca" type in the Rust ecosystem, @@ -888,7 +898,7 @@ impl InstanceEnv { // Check if we have a blocked IP address, since IP literals bypass DNS resolution. if is_blocked_ip_literal(reqwest.url()) { - return Err(http_error(BLOCKED_HTTP_ADDRESS_ERROR)); + return Err(NodesError::HttpError(BLOCKED_HTTP_ADDRESS_ERROR.to_string())); } let redirect_policy = reqwest::redirect::Policy::custom(|attempt| {