From b3ed1c0f8098bbc8af13c29ff76ac82f6fd2474d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BE=B7=E5=AE=87?= Date: Sat, 3 Oct 2026 10:51:29 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8F=91=E8=A1=8C=E5=8C=85=E4=B8=8A=E4=BC=A0?= =?UTF-8?q?=E6=8A=BD=20server=5Ferror=5Fdetail=EF=BC=8C=E7=BB=9F=E4=B8=80?= =?UTF-8?q?=20message/code/=E5=85=9C=E5=BA=95=E9=A1=BA=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - game_package_upload.rs 新增 pub(crate) server_error_detail,统一先取非空 message 再退非空 code 的顺序 - runtime.rs 五处 HTTP 错误分支改用该 helper,删除各自复制的过滤逻辑 - game_distribution_publish.rs 的 response_data 与 map_http_error 共用同一 helper - FORBIDDEN 分支改用 helper,补上此前缺失的空 message trim 过滤 --- .../src/game_distribution_publish.rs | 19 ++++++-------- .../src-tauri/src/game_package_upload.rs | 13 ++++++++++ .../src/game_package_upload/runtime.rs | 25 ++++--------------- 3 files changed, 26 insertions(+), 31 deletions(-) diff --git a/apps/ai-game-creator-shell/src-tauri/src/game_distribution_publish.rs b/apps/ai-game-creator-shell/src-tauri/src/game_distribution_publish.rs index b4bf84b03..ca41e3fd8 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/game_distribution_publish.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/game_distribution_publish.rs @@ -5,8 +5,9 @@ //! 其它素材上传链路。 use crate::game_package_upload::{ - game_package_upload_staging_dir, stage_game_package_bytes, upload_staged_game_package, - GamePackageUploadOutcome, GamePackageUploadRequest, StagedGamePackage, + game_package_upload_staging_dir, server_error_detail, stage_game_package_bytes, + upload_staged_game_package, GamePackageUploadOutcome, GamePackageUploadRequest, + StagedGamePackage, }; use crate::http_client::agc_main_site_client_builder; use crate::platform_session::{ @@ -194,10 +195,9 @@ fn response_data(body: &str) -> Result { serde_json::from_str(body).map_err(|error| format!("服务端响应不是合法 JSON:{error}"))?; if value.get("ok").and_then(Value::as_bool) == Some(false) { let (code, message) = parse_error_payload(body); - return Err(message - .filter(|detail| !detail.trim().is_empty()) - .or_else(|| code.filter(|detail| !detail.trim().is_empty())) - .unwrap_or_else(|| "服务器未返回错误信息".to_string())); + return Err(server_error_detail(code, message, || { + "服务器未返回错误信息".to_string() + })); } Ok(value.get("data").cloned().unwrap_or(value)) } @@ -211,13 +211,10 @@ fn map_http_error(status: StatusCode, body: &str, fallback: &str) -> String { if status == StatusCode::FORBIDDEN { return format!( "permission-denied: {}", - message.unwrap_or_else(|| "当前账号无权执行此操作".to_string()) + server_error_detail(code, message, || "当前账号无权执行此操作".to_string()) ); } - let detail = message - .filter(|value| !value.trim().is_empty()) - .or_else(|| code.filter(|value| !value.trim().is_empty())) - .unwrap_or_else(|| format!("HTTP {}", status.as_u16())); + let detail = server_error_detail(code, message, || format!("HTTP {}", status.as_u16())); format!("{fallback}:{detail}") } diff --git a/apps/ai-game-creator-shell/src-tauri/src/game_package_upload.rs b/apps/ai-game-creator-shell/src-tauri/src/game_package_upload.rs index 42ede48ea..d90d18c3d 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/game_package_upload.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/game_package_upload.rs @@ -134,6 +134,19 @@ fn parse_server_error(status: u16, body: &str) -> (Option, Option, + message: Option, + fallback: impl FnOnce() -> String, +) -> String { + message + .filter(|detail| !detail.trim().is_empty()) + .or_else(|| code.filter(|detail| !detail.trim().is_empty())) + .unwrap_or_else(fallback) +} + /// 从 409 响应里取权威已收字节;取不到就返回 `None`,由调用方按失败处理。 fn parse_received_bytes(body: &str) -> Option { let parsed = serde_json::from_str::(body).ok()?; diff --git a/apps/ai-game-creator-shell/src-tauri/src/game_package_upload/runtime.rs b/apps/ai-game-creator-shell/src-tauri/src/game_package_upload/runtime.rs index b06eb543a..9fc2f6ce9 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/game_package_upload/runtime.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/game_package_upload/runtime.rs @@ -155,10 +155,7 @@ async fn read_upload_state( })?; if status >= 400 { let (code, message) = parse_server_error(status, &body); - let detail = message - .filter(|detail| !detail.trim().is_empty()) - .or_else(|| code.filter(|detail| !detail.trim().is_empty())) - .unwrap_or_else(|| format!("HTTP {status}")); + let detail = server_error_detail(code, message, || format!("HTTP {status}")); return Err(GamePackageUploadError::read_upload_state(detail)); } let parsed: Value = serde_json::from_str(&body).map_err(|error| { @@ -213,30 +210,21 @@ async fn upload_chunk( })?; return Ok(received); } - let detail = message - .filter(|detail| !detail.trim().is_empty()) - .or_else(|| code.filter(|detail| !detail.trim().is_empty())) - .unwrap_or_else(|| format!("HTTP {status}")); + let detail = server_error_detail(code, message, || format!("HTTP {status}")); return Err(ChunkUploadError::Fatal( GamePackageUploadError::upload_chunk(detail), )); } if status >= 500 || status == 408 || status == 429 { let (code, message) = parse_server_error(status, &text); - let detail = message - .filter(|detail| !detail.trim().is_empty()) - .or_else(|| code.filter(|detail| !detail.trim().is_empty())) - .unwrap_or_else(|| format!("HTTP {status}")); + let detail = server_error_detail(code, message, || format!("HTTP {status}")); return Err(ChunkUploadError::Retryable( GamePackageUploadError::upload_chunk(detail), )); } if status >= 400 { let (code, message) = parse_server_error(status, &text); - let detail = message - .filter(|detail| !detail.trim().is_empty()) - .or_else(|| code.filter(|detail| !detail.trim().is_empty())) - .unwrap_or_else(|| format!("HTTP {status}")); + let detail = server_error_detail(code, message, || format!("HTTP {status}")); return Err(ChunkUploadError::Fatal( GamePackageUploadError::upload_chunk(detail), )); @@ -285,10 +273,7 @@ async fn complete_upload( })?; if status >= 400 { let (code, message) = parse_server_error(status, &text); - let detail = message - .filter(|detail| !detail.trim().is_empty()) - .or_else(|| code.filter(|detail| !detail.trim().is_empty())) - .unwrap_or_else(|| format!("HTTP {status}")); + let detail = server_error_detail(code, message, || format!("HTTP {status}")); return Err(GamePackageUploadError::complete_upload(detail)); } let parsed: Value = serde_json::from_str(&text).map_err(|error| {