From f059d5033155a84551d3bcad25268c956c50f0a4 Mon Sep 17 00:00:00 2001 From: Nige Date: Sun, 15 Mar 2026 05:49:42 +0000 Subject: [PATCH] fix: preserve AuthError type in oauth_http_client cache (#1152) * fix(mcp): cache oauth client init error as AuthError * Update src/tools/mcp/auth.rs Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> * fix(mcp): use AuthError::Http in oauth client cache and add regression test * test(mcp): annotate test assert for no-panics CI matcher --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- src/tools/mcp/auth.rs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/tools/mcp/auth.rs b/src/tools/mcp/auth.rs index 7a8e384f..1926e78d 100644 --- a/src/tools/mcp/auth.rs +++ b/src/tools/mcp/auth.rs @@ -24,7 +24,7 @@ use crate::tools::mcp::config::McpServerConfig; /// Per-request timeouts can override the default via `.timeout()` on /// the request builder. fn oauth_http_client() -> Result<&'static reqwest::Client, AuthError> { - static CLIENT: std::sync::OnceLock> = + static CLIENT: std::sync::OnceLock> = std::sync::OnceLock::new(); CLIENT .get_or_init(|| { @@ -32,10 +32,10 @@ fn oauth_http_client() -> Result<&'static reqwest::Client, AuthError> { .timeout(Duration::from_secs(30)) .redirect(reqwest::redirect::Policy::none()) .build() - .map_err(|e| e.to_string()) + .map_err(|e| AuthError::Http(e.to_string())) }) .as_ref() - .map_err(|e| AuthError::Http(e.clone())) + .map_err(Clone::clone) } /// Log a debug message when a discovery/auth response is a redirect. @@ -57,7 +57,7 @@ fn log_redirect_if_applicable(url: &str, response: &reqwest::Response) { } /// OAuth authorization error. -#[derive(Debug, thiserror::Error)] +#[derive(Debug, Clone, thiserror::Error)] pub enum AuthError { #[error("Server does not support OAuth authorization")] NotSupported, @@ -1520,6 +1520,17 @@ mod tests { } } + #[test] + fn test_auth_error_clone_preserves_http_variant_and_payload() { + let original = AuthError::Http("builder failed".to_string()); + let cloned = original.clone(); + + match cloned { + AuthError::Http(message) => assert_eq!(message, "builder failed"), // safety: test assertion in #[cfg(test)] module; not production panic path + other => panic!("expected AuthError::Http variant, got {other:?}"), + } + } + // --- New tests for well-known URI construction --- #[test]