Hmbown/CodeWhale · error

failed to build HTTP client

Error message

failed to build HTTP client

What it means

`FinanceTool::new()` builds a reqwest HTTP client via `crate::tls::reqwest_client_builder().user_agent(USER_AGENT).build()` and unwraps the result with `expect("failed to build HTTP client")`. reqwest's `build()` fails when the TLS backend cannot be initialized (e.g. native-tls cannot load the system OpenSSL, or rustls cannot be constructed) or when a user-agent header value is invalid. The tool treats client construction as a hard precondition, so failure panics instead of returning a Result.

Solutions

  1. Verify the TLS backend is available in the deployment environment (install ca-certificates / libssl matching the target, or switch the builder to rustls with a working crypto provider).
  2. Reproduce locally by calling `crate::tls::reqwest_client_builder().build()` and inspect the returned reqwest::Error for the root cause.
  3. If the panic is unacceptable in your context, add a fallible constructor (try_new -> Result) and surface the error instead of panicking.
  4. Check USER_AGENT for non-visible-ASCII characters that make the header value invalid.

Example fix

// before
client: crate::tls::reqwest_client_builder()
    .user_agent(USER_AGENT)
    .build()
    .expect("failed to build HTTP client"),
// after
client: crate::tls::reqwest_client_builder()
    .user_agent(USER_AGENT)
    .build()
    .map_err(|e| ToolInitError::HttpClient(format!("finance tool init: {e}")))?,
Defensive patterns

Strategy: fallback

Validate before calling

// At startup, before constructing FinanceTool:
let probe = crate::tls::reqwest_client_builder().build();
if let Err(e) = probe { eprintln!("TLS/HTTP client unavailable: {e}"); }

Try / catch

// If you must call new() in fallible context:
let tool = std::panic::catch_unwind(FinanceTool::new)
    .map_err(|_| anyhow::anyhow!("finance tool unavailable: HTTP client init failed"))?;

Prevention

When it happens

Trigger: Calling `FinanceTool::new()` (or `with_endpoints`) in an environment where the TLS backend init fails: missing/broken OpenSSL shared libraries, a rustls crypto provider misconfiguration, or `USER_AGENT` containing characters invalid for a header value.

Common situations: Deploying to a slim/container image without CA certificates or OpenSSL; cross-compiling with a TLS backend not linked for the target; corrupting the USER_AGENT constant during an edit.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/f50bd2c57486de9c. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/tools/finance.rs:160

    fn summary(&self) -> String {
        format!("{}: {}", self.endpoint, self.detail)
    }
}

pub struct FinanceTool {
    endpoints: FinanceEndpoints,
    client: Client,
}

impl FinanceTool {
    #[must_use]
    pub fn new() -> Self {
        Self {
            endpoints: FinanceEndpoints::default(),
            client: crate::tls::reqwest_client_builder()
                .user_agent(USER_AGENT)
                .build()
                .expect("failed to build HTTP client"),
        }
    }

    #[cfg(test)]
    fn with_endpoints(quote_base: impl Into<String>, chart_base: impl Into<String>) -> Self {
        Self {
            endpoints: FinanceEndpoints {
                quote_base: quote_base.into(),
                chart_base: chart_base.into(),
            },
            client: crate::tls::reqwest_client_builder()
                .user_agent(USER_AGENT)
                .build()
                .expect("failed to build HTTP client"),
        }
    }
}

View on GitHub (pinned to 73e0f67d83)