From ccfcd4bfdeee60b5f1dde2eca1eb16a46481aeb7 Mon Sep 17 00:00:00 2001 From: willamhou Date: Sun, 15 Mar 2026 19:35:39 +0800 Subject: [PATCH] refactor: propagate error from Client::builder instead of silent fallback Address review feedback: `unwrap_or_else(|_| Client::new())` silently drops the configured timeout on builder failure. Change `new()` to return `Result` and propagate with `?` instead. Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude Co-Authored-By: Happy --- src/tunnel/custom.rs | 33 +++++++++++++++++++-------------- src/tunnel/mod.rs | 2 +- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/tunnel/custom.rs b/src/tunnel/custom.rs index 81211da8..98286049 100644 --- a/src/tunnel/custom.rs +++ b/src/tunnel/custom.rs @@ -1,6 +1,6 @@ //! Custom tunnel via an arbitrary shell command. -use anyhow::{Result, bail}; +use anyhow::{Context, Result, bail}; use tokio::io::AsyncBufReadExt; use tokio::process::Command; @@ -35,18 +35,19 @@ impl CustomTunnel { start_command: String, health_url: Option, url_pattern: Option, - ) -> Self { - Self { + ) -> Result { + let http_client = reqwest::Client::builder() + .timeout(std::time::Duration::from_secs(5)) + .build() + .context("failed to create HTTP client for tunnel health checks")?; + Ok(Self { start_command, health_url, url_pattern, proc: new_shared_process(), url: new_shared_url(), - http_client: reqwest::Client::builder() - .timeout(std::time::Duration::from_secs(5)) - .build() - .unwrap_or_else(|_| reqwest::Client::new()), - } + http_client, + }) } } @@ -178,7 +179,7 @@ mod tests { #[tokio::test] async fn empty_command_returns_error() { - let tunnel = CustomTunnel::new(" ".into(), None, None); + let tunnel = CustomTunnel::new(" ".into(), None, None).unwrap(); let result = tunnel.start("127.0.0.1", 8080).await; assert!(result.is_err()); assert!( @@ -191,7 +192,7 @@ mod tests { #[tokio::test] async fn start_without_pattern_returns_local() { - let tunnel = CustomTunnel::new("sleep 1".into(), None, None); + let tunnel = CustomTunnel::new("sleep 1".into(), None, None).unwrap(); let url = tunnel.start("127.0.0.1", 4455).await.unwrap(); assert_eq!(url, "http://127.0.0.1:4455"); tunnel.stop().await.unwrap(); @@ -203,7 +204,8 @@ mod tests { "echo https://public.example".into(), None, Some("public.example".into()), - ); + ) + .unwrap(); let url = tunnel.start("localhost", 9999).await.unwrap(); assert_eq!(url, "https://public.example"); tunnel.stop().await.unwrap(); @@ -218,7 +220,8 @@ mod tests { r"printf http://internal:1234\nhttps://real.tunnel.io/abc\n".into(), None, Some("tunnel.io".into()), - ); + ) + .unwrap(); let url = tunnel.start("localhost", 9999).await.unwrap(); assert_eq!(url, "https://real.tunnel.io/abc"); tunnel.stop().await.unwrap(); @@ -230,7 +233,8 @@ mod tests { "echo http://{host}:{port}".into(), None, Some("http://".into()), - ); + ) + .unwrap(); let url = tunnel.start("10.1.2.3", 4321).await.unwrap(); assert_eq!(url, "http://10.1.2.3:4321"); tunnel.stop().await.unwrap(); @@ -243,7 +247,8 @@ mod tests { "sleep 1".into(), Some("http://192.0.2.1:9999/healthz".into()), None, - ); + ) + .unwrap(); assert!( !tunnel.health_check().await, "Health check should fail for unreachable URL" diff --git a/src/tunnel/mod.rs b/src/tunnel/mod.rs index fa028834..d953dafb 100644 --- a/src/tunnel/mod.rs +++ b/src/tunnel/mod.rs @@ -171,7 +171,7 @@ pub fn create_tunnel(config: &TunnelProviderConfig) -> Result bail!(