From b54b3794f648078289d6bff01881f16697d7a938 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BE=B7=E5=AE=87?= Date: Fri, 2 Oct 2026 11:50:43 +0800 Subject: [PATCH] =?UTF-8?q?=E7=99=BB=E5=BD=95=E8=B7=AF=E7=94=B1=E7=9A=8442?= =?UTF-8?q?9=E5=BD=92=E4=B8=9A=E5=8A=A1=E5=8F=98=E4=BD=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - map_auth_failure 的 429 改为按路由判定:SendCode 仍是 SmsCodeThrottled,PhoneLogin 映射为 PhoneCodeLoginRejected(用户可修正、不进错误池),其余路由才落 UnexpectedRejection - 补用例覆盖登录 429 与其它路由 429;map_auth_failure 注释同步新口径 --- .../src-tauri/src/auth_session.rs | 43 +++++++++++++++++-- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/apps/ai-game-creator-shell/src-tauri/src/auth_session.rs b/apps/ai-game-creator-shell/src-tauri/src/auth_session.rs index 416566950..c65cba3ac 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/auth_session.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/auth_session.rs @@ -501,7 +501,8 @@ fn auth_route(route: &str) -> AuthRoute { /// /// 会话路由的 `401/403` 归到权威失效变体,调用方据此清会话;登录路由的 `401` 是用户可修正的 /// 输入问题。可判定的用户输入原因只进业务变体,认不出的才落到 `UnexpectedRejection`。 -/// 网络、5xx 与契约异常必须保留会话。 +/// `429` 也按路由判定:发码路由是频控,登录路由是「验证码错误次数过多」,两者都是用户可修正的 +/// 输入问题;其余路由的 `429` 仍按未识别拒绝处理。网络、5xx 与契约异常必须保留会话。 fn map_auth_failure(status: StatusCode, body: &str, route: AuthRoute) -> ClientAuthError { crate::platform_maintenance::watch_platform_response(status.as_u16(), body); let status_code = status.as_u16(); @@ -526,8 +527,17 @@ fn map_auth_failure(status: StatusCode, body: &str, route: AuthRoute) -> ClientA }), }; } - if status == StatusCode::TOO_MANY_REQUESTS && route == AuthRoute::SendCode { - return ClientAuthError::SmsCodeThrottled; + if status == StatusCode::TOO_MANY_REQUESTS { + return match route { + AuthRoute::SendCode => ClientAuthError::SmsCodeThrottled, + AuthRoute::PhoneLogin => { + ClientAuthError::PhoneCodeLoginRejected(PhoneCodeLoginRejected { server_message }) + } + _ => ClientAuthError::UnexpectedRejection(UnexpectedRejection { + status: status_code, + server_message, + }), + }; } if status == StatusCode::BAD_REQUEST { return match route { @@ -1350,6 +1360,33 @@ mod tests { ); assert_eq!(throttled, ClientAuthError::SmsCodeThrottled); + // 登录路由的 429 是「验证码错误次数过多」:用户可修正的输入问题,不能进系统变体被上报。 + let verify_attempts_exceeded = map_auth_failure( + StatusCode::TOO_MANY_REQUESTS, + r#"{"error":{"message":"验证码错误次数过多,请重新获取验证码"}}"#, + AuthRoute::PhoneLogin, + ); + assert_eq!( + verify_attempts_exceeded, + ClientAuthError::PhoneCodeLoginRejected(PhoneCodeLoginRejected { + server_message: Some("验证码错误次数过多,请重新获取验证码".to_string()), + }) + ); + + // 其余路由的 429 仍未识别拒绝:既不冒充业务原因,也不冒充发码频控。 + let unknown_throttle = map_auth_failure( + StatusCode::TOO_MANY_REQUESTS, + r#"{"error":{"message":"限流"}}"#, + AuthRoute::Other, + ); + assert_eq!( + unknown_throttle, + ClientAuthError::UnexpectedRejection(UnexpectedRejection { + status: 429, + server_message: Some("限流".to_string()), + }) + ); + let bad_code = map_auth_failure( StatusCode::UNAUTHORIZED, r#"{"error":{"message":"验证码错误"}}"#,