From 0798bf52194237d8ab6644e54f90e358a93a9dcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BE=B7=E5=AE=87?= Date: Thu, 1 Oct 2026 20:35:47 +0800 Subject: [PATCH] =?UTF-8?q?AGC=20=E8=AE=A4=E8=AF=81=E7=BB=AD=E6=9C=9F?= =?UTF-8?q?=E5=A4=B1=E8=B4=A5=E4=B8=8D=E5=86=8D=E9=99=8D=E7=BA=A7=E6=88=90?= =?UTF-8?q?=E5=AD=97=E7=AC=A6=E4=B8=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - refresh_session_inner 的非权威失败直接返回 Err(ClientAuthError),不再折成 error_message 字符串 - ClientAuthStateView 删除 error_message 字段,状态收窄为 authenticated / unauthenticated - ClientAuthRefreshView 删除 error_message 与 failed 状态,authoritative 只在未登录时为 true - read_client_auth_state 把续期失败原样透传给命令出口,不再投影出 unavailable 第三态 --- .../src-tauri/src/auth_session.rs | 52 ++++--------------- 1 file changed, 11 insertions(+), 41 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 efb7a210c..592f5ef95 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 @@ -49,14 +49,12 @@ const AUTH_AUTHORITY_MESSAGE: &str = "登录状态已失效,请重新登录"; #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] #[serde(rename_all = "camelCase")] pub(crate) struct ClientAuthStateView { - /// `authenticated` / `unauthenticated` / `unavailable`。 + /// `authenticated` / `unauthenticated`。 pub(crate) status: String, #[serde(default, skip_serializing_if = "Option::is_none")] pub(crate) user: Option, #[serde(default, skip_serializing_if = "Option::is_none")] pub(crate) api_base_url: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub(crate) error_message: Option, } #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] @@ -66,18 +64,17 @@ pub(crate) struct ClientLoginCodeView { pub(crate) expires_in_seconds: u64, } -/// 续期结果。`stale` 表示续期期间身份已经变化,调用方不得重放旧身份请求。 +/// 续期结果。`stale` 表示续期期间身份已经变化,调用方不得重放旧身份请求; +/// 非权威失败(网络 / 5xx / 契约异常)不在这里降级成字符串,直接以 `Err(ClientAuthError)` 返回。 #[derive(Clone, Debug, PartialEq, Serialize)] #[serde(rename_all = "camelCase")] pub(crate) struct ClientAuthRefreshView { - /// `refreshed` / `unauthenticated` / `stale` / `failed`。 + /// `refreshed` / `unauthenticated` / `stale`。 pub(crate) status: String, #[serde(default, skip_serializing_if = "Option::is_none")] pub(crate) user: Option, #[serde(default)] pub(crate) authoritative: bool, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub(crate) error_message: Option, } #[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)] @@ -808,7 +805,6 @@ fn auth_state_view( status: status.to_string(), user, api_base_url, - error_message: None, } } @@ -886,7 +882,6 @@ async fn refresh_session_inner( status: "unauthenticated".to_string(), user: None, authoritative: true, - error_message: None, }); }; let _guard = refresh_lock().lock().await; @@ -902,7 +897,6 @@ async fn refresh_session_inner( status: "refreshed".to_string(), user: Some(user), authoritative: false, - error_message: None, }); } } @@ -934,15 +928,11 @@ async fn refresh_session_inner( status: "unauthenticated".to_string(), user: None, authoritative: true, - error_message: None, }); } - return Ok(ClientAuthRefreshView { - status: "failed".to_string(), - user: None, - authoritative: false, - error_message: Some(error.message().to_string()), - }); + // 非权威失败不再降级成字符串:把 typed error 原样交给命令出口, + // 由前端 `invokeClientAuth` 转成 `ClientAuthFailure` 并按变体分流。 + return Err(error); } }; let token: TokenResponse = serde_json::from_value(refreshed.data).map_err(|_| { @@ -977,7 +967,6 @@ async fn refresh_session_inner( status: "stale".to_string(), user: None, authoritative: false, - error_message: None, }); } let view = auth_state_view( @@ -990,7 +979,6 @@ async fn refresh_session_inner( status: "refreshed".to_string(), user: Some(user), authoritative: false, - error_message: None, }) } Ok(None) => { @@ -1001,7 +989,6 @@ async fn refresh_session_inner( status: "unauthenticated".to_string(), user: None, authoritative: true, - error_message: None, }) } Err(error) if error.is_authority_failure() => { @@ -1012,15 +999,9 @@ async fn refresh_session_inner( status: "unauthenticated".to_string(), user: None, authoritative: true, - error_message: None, }) } - Err(error) => Ok(ClientAuthRefreshView { - status: "failed".to_string(), - user: None, - authoritative: false, - error_message: Some(error.message().to_string()), - }), + Err(error) => Err(error), } } @@ -1063,20 +1044,10 @@ pub(crate) async fn read_client_auth_state( refresh.user, Some(session.api_base_url), )), - "stale" | "unauthenticated" => Ok(auth_state_view("unauthenticated", None, None)), - _ => Ok(ClientAuthStateView { - status: "unavailable".to_string(), - user: None, - api_base_url: Some(session.api_base_url), - error_message: refresh.error_message, - }), + // `stale`(续期期间身份已变化)与 `unauthenticated` 都按未登录处理。 + _ => Ok(auth_state_view("unauthenticated", None, None)), }, - Err(error) => Ok(ClientAuthStateView { - status: "unavailable".to_string(), - user: None, - api_base_url: Some(session.api_base_url), - error_message: Some(error.message().to_string()), - }), + Err(error) => Err(error), } } @@ -1493,7 +1464,6 @@ mod tests { wechat_account: None, }), api_base_url: Some(DEVELOPMENT_ORIGIN.to_string()), - error_message: None, }; let serialized = serde_json::to_string(&view).expect("serialize auth state"); for forbidden in [