what-core 1.6.0

Core framework for What - an HTML-first web framework powered by Rust
Documentation
use std::panic::{self, AssertUnwindSafe};
use std::time::Duration;

fn panic_message(payload: Box<dyn std::any::Any + Send>) -> String {
    if let Some(msg) = payload.downcast_ref::<&str>() {
        (*msg).to_string()
    } else if let Some(msg) = payload.downcast_ref::<String>() {
        msg.clone()
    } else {
        "unknown panic".to_string()
    }
}

fn build_once(
    timeout: Option<Duration>,
    disable_proxy_autodiscovery: bool,
) -> Result<reqwest::Client, String> {
    let mut builder = reqwest::Client::builder();
    if let Some(timeout) = timeout {
        builder = builder.timeout(timeout);
    }
    if disable_proxy_autodiscovery {
        builder = builder.no_proxy();
    }

    match panic::catch_unwind(AssertUnwindSafe(|| builder.build())) {
        Ok(Ok(client)) => Ok(client),
        Ok(Err(err)) => Err(err.to_string()),
        Err(payload) => Err(panic_message(payload)),
    }
}

/// Build a reqwest client without letting system proxy autodiscovery panic the process.
///
/// The first attempt keeps normal proxy behavior. If that fails or panics, fall back
/// to `no_proxy()` so framework startup remains deterministic across environments.
pub(crate) fn build_http_client(timeout: Option<Duration>) -> Result<reqwest::Client, String> {
    match build_once(timeout, false) {
        Ok(client) => Ok(client),
        Err(primary_err) => {
            tracing::warn!(
                "HTTP client build failed with system proxy autodiscovery: {}. Retrying without proxies.",
                primary_err
            );
            build_once(timeout, true).map_err(|fallback_err| {
                format!(
                    "primary build failed: {}; fallback without proxies failed: {}",
                    primary_err, fallback_err
                )
            })
        }
    }
}