diff --git a/src-tauri/src/proxy/handlers.rs b/src-tauri/src/proxy/handlers.rs index b16bf2715..96076470d 100644 --- a/src-tauri/src/proxy/handlers.rs +++ b/src-tauri/src/proxy/handlers.rs @@ -1005,19 +1005,39 @@ fn codex_proxy_error_json( return body; }; - let cause = error_obj - .get("message") - .and_then(|value| value.as_str()) - .map(ToString::to_string) - .filter(|message| !message.trim().is_empty()) - .unwrap_or_else(|| get_error_message(error)); - - let status_fragment = upstream_status - .map(|status| format!("; upstream_status: HTTP {status}")) - .unwrap_or_default(); - let message = format!( - "CC Switch local proxy failed while handling Codex endpoint {endpoint}. Provider: {provider_name}; model: {request_model}{status_fragment}; cause: {cause}" - ); + let message = if upstream_status == Some(413) { + // 413 来自上游渠道商的网关(典型是 nginx 的 client_max_body_size),不是 CC + // Switch 本地代理的限制(本地 DefaultBodyLimit 已放到 200MB)。上游响应体往往是 + // 一整段 nginx HTML,对用户毫无价值,这里替换成明确指向上游 + 可操作的指引, + // 避免「以为是 CC Switch 封装了 nginx / 是本地代理的锅」这种反复出现的误解。 + format!( + concat!( + "Upstream provider rejected the request with HTTP 413 (Payload Too Large). ", + "The request body exceeds the upstream gateway's size limit; this is the ", + "provider's server-side limit, not a CC Switch limit. ", + "Provider: {provider}; model: {model}; endpoint: {endpoint}. ", + "To recover, shrink the request: run /compact, remove large pasted logs or ", + "inline images, or ask the provider to raise its request body limit ", + "(e.g. nginx client_max_body_size)." + ), + provider = provider_name, + model = request_model, + endpoint = endpoint, + ) + } else { + let cause = error_obj + .get("message") + .and_then(|value| value.as_str()) + .map(ToString::to_string) + .filter(|message| !message.trim().is_empty()) + .unwrap_or_else(|| get_error_message(error)); + let status_fragment = upstream_status + .map(|status| format!("; upstream_status: HTTP {status}")) + .unwrap_or_default(); + format!( + "CC Switch local proxy failed while handling Codex endpoint {endpoint}. Provider: {provider_name}; model: {request_model}{status_fragment}; cause: {cause}" + ) + }; error_obj.insert( "message".to_string(), @@ -1477,4 +1497,36 @@ data: {\"type\":\"response.output_item.done\",\"item\":{\"type\":\"message\"}}\n assert_eq!(body["error"]["code"], 2013); assert_eq!(body["error"]["upstream_status"], 502); } + + #[test] + fn codex_proxy_413_points_to_upstream_not_local_proxy() { + // 模拟上游渠道商 nginx 因 client_max_body_size 返回的 413 HTML 页面 + // (见 issue #666:长上下文 / 大图 / 大日志撞上游体积上限) + let error = ProxyError::UpstreamError { + status: 413, + body: Some( + "\r\n