修复错误正文收敛合并引入的两处失败测试
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust crates (pull_request) Has been cancelled
Project CI / Backend tests (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled
Project CI / Frontend tests (pull_request) Has been cancelled
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / AI game creator shell web tests (pull_request) Has been cancelled

模型目录 ok=true 但 data 为空时恢复服务端协议 error 明细,补回合并时丢失的分支实现
自定义模型端点失败时不再回显上游正文,仅返回 HTTP 状态码,避免泄漏密钥
使 catalog_missing_data_preserves_protocol_detail 与 custom_llm_discovery_reports_safe_errors_and_bounds_response 恢复通过
This commit is contained in:
2026-10-07 13:02:47 +08:00
parent 05012a85c3
commit d7b6dce393
2 changed files with 17 additions and 18 deletions
@@ -4487,21 +4487,12 @@ pub(crate) async fn fetch_custom_llm_models(
.await
.map_err(|error| format!("无法连接模型端点:{error};请检查 API 地址和网络"))?;
if !response.status().is_success() {
let status = response.status();
let body = response
.text()
.await
.unwrap_or_else(|error| format!("响应正文读取失败:{error}"));
let detail = crate::agent::redact_agent_runtime_error(
Path::new("__agc_no_project_root__"),
body.trim(),
600,
);
return Err(if detail.is_empty() {
format!("模型列表读取失败(HTTP {})", status.as_u16())
} else {
format!("模型列表读取失败(HTTP {}):{detail}", status.as_u16())
});
// 自定义模型端点由用户提供、响应不可信:只回报状态码,绝不回显上游正文,
// 否则会把密钥或私有数据带进错误文案。
return Err(format!(
"模型列表读取失败(HTTP {})",
response.status().as_u16()
));
}
let mut body = Vec::new();
while let Some(chunk) = response
@@ -53,9 +53,17 @@ fn parse_catalog_payload(bytes: &[u8]) -> Result<LlmModelsResponse, String> {
.unwrap_or("模型列表读取失败");
return Err(message.to_string());
}
return envelope
.data
.ok_or_else(|| "模型列表响应缺少 data,请稍后重试".to_string());
return envelope.data.ok_or_else(|| {
// `ok=true` 但 `data` 为空时,把服务端协议里的 error 明细带出来,
// 否则排障只能看到笼统的「缺少 data」。
let error_detail = envelope
.error
.as_ref()
.and_then(|error| error.message.as_deref().or(error.code.as_deref()))
.filter(|detail| !detail.trim().is_empty())
.unwrap_or("error 字段为空");
format!("模型列表响应缺少 data:ok=true,error={error_detail}")
});
}
serde_json::from_value::<LlmModelsResponse>(value)