3.4 KiB
3.4 KiB
plan.html 500 错误调试备忘(2026-06-18)
问题现象
用户反馈:http://www.zszs.site/plan.html 显示"⚠️ 生成失败:AI 服务响应异常(状态500)"
调试路径
1. 先确认是哪个 API 返回 500
# 测试概率接口(plan.html 第一步)
curl -s -w "\nHTTP: %{http_code}" "http://www.zszs.site/api/prob" \
-X POST -H "Content-Type: application/json" \
-d '{"score":580,"subject":"历史类"}'
# 返回 400 → 分数超出范围,或 500 → 其他逻辑错误
2. 查服务器日志
# 所有错误都在这个文件里
sshpass -p 'xue.2538' ssh root@192.144.179.11 'tail -50 /tmp/gaokao.log'
3. 本次根因:schools.db 是空的,gaokao_henan.db 才是真库
# 确认数据库文件
sshpass -p 'xue.2538' ssh root@192.144.179.11 'ls -la /www/wwwroot/gaokao/*.db'
# gaokao_henan.db 是真库(35MB),schools.db 是空的(0字节)
# Python 代码里的 DB_PATH 指向 gaokao_henan.db
4. 本次根因2:subject 字段映射断裂
前端 plan.html 发送的 subject 值:
| 表单选项 | 实际发送 | yiyi 表字段 | schools 表字段 |
|---|---|---|---|
| 物理类(理科) | 物理类 |
物理类 |
理科 |
| 历史类(文科) | 历史类 |
历史类 |
文科 |
/api/prob 路由调用链:
plan.html POST {subject:"历史类"}
↓
score_to_rank(yiyi表, subject="历史类") ← 正确,yiyi表用 历史类/物理类
↓ 但 schools 表查的是原始值(不过滤),所以实际只依赖 yiyi 表做 rank 换算
↓
问题:前端如果发"文科"而不是"历史类",yiyi 查不到,score_to_rank 返回 null
↓
if not student_rank: return 400 ← 但后面概率计算逻辑还有问题导致 500
2026-06-18 发现:/api/prob 路由里没有 subject 映射,
导致发"理科"时 yiyi 查不到,student_rank=null → 400后继续执行 → 后续逻辑报错 500
修复:在 /api/prob 路由里加映射:
subject_map = {'文科': '历史类', '理科': '物理类'}
subject = subject_map.get(subject, subject)
5. 快速验证修复
# 用 历史类(数据库值)测试
curl -s "http://www.zszs.site/api/prob" -X POST -H "Content-Type: application/json" \
-d '{"score":580,"subject":"历史类"}' | python3 -c "
import sys,json
d=json.load(sys.stdin)
print('rank:', d.get('rank'))
print('chong:', len(d.get('chong',[])), 'wen:', len(d.get('wen',[])), 'bao:', len(d.get('bao',[])))
"
# 用 文科(前端值)测试
curl -s "http://www.zszs.site/api/prob" -X POST -H "Content-Type: application/json" \
-d '{"score":580,"subject":"文科"}' | python3 -c "
import sys,json
d=json.load(sys.stdin)
print('rank:', d.get('rank'), 'error:', d.get('error'))
"
# 修复后两者都应返回 rank > 0
关键 SQL 查询(用于手动验证数据)
sshpass -p 'xue.2538' ssh root@192.144.179.11 '
/www/server/panel/pyenv/bin/python3 << "PYEOF"
import sqlite3
conn = sqlite3.connect("/www/wwwroot/gaokao/gaokao_henan.db")
cur = conn.cursor()
# yiyi表分数范围(用于 score_to_rank)
cur.execute("SELECT subject, MIN(score), MAX(score) FROM yiyi WHERE year=2025 GROUP BY subject")
print("yiyi表分数范围:", list(cur.fetchall()))
# schools表subject字段分布
cur.execute("SELECT subject, COUNT(*) FROM schools WHERE year=2025 GROUP BY subject LIMIT 10")
print("schools表subject分布:", list(cur.fetchall()))
PYEOF
'