修复积分榜"body stream already read"错误

两个根因:
1. src/api/routes/standings 端点使用 func.max() 但未导入 func → NameError(500)
   → 在 matches.py 的 sqlalchemy 导入中加入 func
2. 前端 api.ts 错误处理中先调 res.json() 失败后回退 res text(),
   但 Response body 流只能读一次 → "body stream already read"
   → 改为先 res.text() 再 JSON.parse(),避免重复读取

Co-Authored-By: new-provider/LongCat-2.0 <<EMAIL>>
This commit is contained in:
shangfangjian
2026-09-20 20:05:40 +08:00
co-authored by new-provider/LongCat-2.0 <
parent f52ec8b963
commit c586a38b3a
2 changed files with 8 additions and 5 deletions
+7 -4
View File
@@ -49,14 +49,17 @@ async function request<T>(
}) })
if (!res.ok) { if (!res.ok) {
let detail: unknown // 先读 text 再尝试 JSON 解析:Response body 流只能读一次,
// 若先调 res.json() 失败(如返回 HTML 错误页),再调 res.text() 会抛 "body stream already read"。
const rawText = await res.text()
let detail: unknown = rawText
try { try {
detail = await res.json() detail = JSON.parse(rawText)
} catch { } catch {
detail = await res.text() // 非 JSON(如 HTML 错误页),保留原始文本
} }
let message = let message =
detail && typeof detail === 'object' && 'detail' in detail detail && typeof detail === 'object' && detail !== null && 'detail' in detail
? String((detail as { detail: unknown }).detail) ? String((detail as { detail: unknown }).detail)
: `HTTP ${res.status}: ${res.statusText}` : `HTTP ${res.status}: ${res.statusText}`
// 401 仅在没有显式跳过时广播未登录事件(改密接口的 401 表示当前密码错误,非会话过期) // 401 仅在没有显式跳过时广播未登录事件(改密接口的 401 表示当前密码错误,非会话过期)
+1 -1
View File
@@ -4,7 +4,7 @@ from __future__ import annotations
from datetime import datetime, timedelta from datetime import datetime, timedelta
from fastapi import APIRouter, Depends, HTTPException, Query from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy import or_, select from sqlalchemy import func, or_, select
from sqlalchemy.orm import selectinload from sqlalchemy.orm import selectinload
from src.api.deps import require_admin from src.api.deps import require_admin