v0.7.2测试

This commit is contained in:
2026-04-15 12:36:37 +08:00
parent 3ba87367df
commit 7c743293be
5 changed files with 77 additions and 33 deletions

View File

@@ -367,3 +367,12 @@
- auth.py: change_password路由从请求中读取force参数传递给服务层 - auth.py: change_password路由从请求中读取force参数传递给服务层
- dashboard.php: 强制改密请求中添加force:true, old_password设为空字符串 - dashboard.php: 强制改密请求中添加force:true, old_password设为空字符串
- 科目管理500和管理员管理500: 经代码审查确认代码逻辑正确SQL、路由、模型均无问题500错误为后端服务未重启导致旧代码仍在运行 - 科目管理500和管理员管理500: 经代码审查确认代码逻辑正确SQL、路由、模型均无问题500错误为后端服务未重启导致旧代码仍在运行
- [x] 12.14 添加全局异常处理器 + 4个500路由添加try-except + 历史记录page_size上限修复
【目标对象】`backend/main.py``backend/routes/subject.py``backend/routes/admin.py``backend/routes/student.py`
【修改目的】用户确认后端已重启但仍报5004个路由持续返回500 Internal Server Error科目管理、管理员管理、历史记录、学生端操行分。无法直接查看后端日志需通过全局异常处理器和路由级try-except捕获具体错误原因
【修改方式】
- main.py: 添加全局异常处理器 global_exception_handler捕获所有未处理异常返回包含str(exc)的message和可选的traceback detail仅DEBUG模式
- subject.py: get_subjects路由添加try-except新增logger导入
- admin.py: get_admins和get_conduct_history路由添加try-exceptget_conduct_history的page_size参数le=100→le=1000
- student.py: get_conduct_history路由添加try-except新增logger导入

View File

@@ -11,7 +11,9 @@
from fastapi import FastAPI, Request from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from contextlib import asynccontextmanager from contextlib import asynccontextmanager
import traceback
import uvicorn import uvicorn
from config import settings from config import settings
@@ -78,6 +80,21 @@ app.add_middleware(
) )
# 全局异常处理器
@app.exception_handler(Exception)
async def global_exception_handler(request: Request, exc: Exception):
"""全局异常处理器 - 捕获所有未处理异常"""
logger.error(f"未处理异常: {exc}", exc_info=True)
return JSONResponse(
status_code=500,
content={
"success": False,
"message": f"服务器内部错误: {str(exc)}",
"detail": traceback.format_exc() if settings.DEBUG else None
}
)
# 注册路由 # 注册路由
app.include_router(auth.router, prefix="/api/auth", tags=["认证"]) app.include_router(auth.router, prefix="/api/auth", tags=["认证"])
app.include_router(student.router, prefix="/api/student", tags=["学生端"]) app.include_router(student.router, prefix="/api/student", tags=["学生端"])

View File

@@ -176,11 +176,12 @@ async def get_conduct_history(
request: Request, request: Request,
student_id: Optional[int] = None, student_id: Optional[int] = None,
page: int = Query(1, ge=1), page: int = Query(1, ge=1),
page_size: int = Query(20, ge=1, le=100), page_size: int = Query(20, ge=1, le=1000),
start_date: Optional[str] = None, start_date: Optional[str] = None,
end_date: Optional[str] = None end_date: Optional[str] = None
): ):
"""获取操行分历史记录""" """获取操行分历史记录"""
try:
user = await get_current_user(request) user = await get_current_user(request)
result = await ConductService.get_history( result = await ConductService.get_history(
user_id=user["user_id"], user_id=user["user_id"],
@@ -191,6 +192,9 @@ async def get_conduct_history(
end_date=end_date end_date=end_date
) )
return success_response(data=result) return success_response(data=result)
except Exception as e:
logger.error(f"获取历史记录失败: {e}", exc_info=True)
return error_response(message=f"获取历史记录失败: {str(e)}", code=500)
# ========== 作业管理 ========== # ========== 作业管理 ==========
@@ -360,9 +364,13 @@ async def add_admin(request: Request, req: AddAdminRequest):
@router.get("/list") @router.get("/list")
async def get_admins(request: Request): async def get_admins(request: Request):
"""获取管理员列表(班主任)""" """获取管理员列表(班主任)"""
try:
user = await get_current_user(request) user = await get_current_user(request)
is_teacher = await PermissionChecker.check_is_teacher(user["user_id"]) is_teacher = await PermissionChecker.check_is_teacher(user["user_id"])
if not is_teacher: if not is_teacher:
return error_response(message="仅班主任可查看管理员列表", code=403) return error_response(message="仅班主任可查看管理员列表", code=403)
result = await AdminService.get_admins() result = await AdminService.get_admins()
return success_response(data=result) return success_response(data=result)
except Exception as e:
logger.error(f"获取管理员列表失败: {e}", exc_info=True)
return error_response(message=f"获取管理员列表失败: {str(e)}", code=500)

View File

@@ -31,6 +31,7 @@ async def get_conduct_history(
""" """
获取学生操行分历史 获取学生操行分历史
""" """
try:
user = await get_current_user(request) user = await get_current_user(request)
# 权限检查:只能查看自己的信息(学生)或同班(管理员) # 权限检查:只能查看自己的信息(学生)或同班(管理员)
@@ -44,6 +45,9 @@ async def get_conduct_history(
) )
return success_response(data=result) return success_response(data=result)
except Exception as e:
logger.error(f"获取学生操行分失败: {e}", exc_info=True)
return error_response(message=f"获取学生操行分失败: {str(e)}", code=500)
@router.get("/homework/{student_id}") @router.get("/homework/{student_id}")

View File

@@ -15,14 +15,20 @@ from middleware.permission import get_current_user, PermissionChecker
from services.subject_service import SubjectService from services.subject_service import SubjectService
from schemas.subject import CreateSubjectRequest, UpdateSubjectRequest from schemas.subject import CreateSubjectRequest, UpdateSubjectRequest
from utils.response import success_response, error_response from utils.response import success_response, error_response
from utils.logger import get_logger
router = APIRouter() router = APIRouter()
logger = get_logger(__name__)
@router.get("/list") @router.get("/list")
async def get_subjects(request: Request, is_active: Optional[bool] = None): async def get_subjects(request: Request, is_active: Optional[bool] = None):
try:
user = await get_current_user(request) user = await get_current_user(request)
result = await SubjectService.get_subjects(is_active=is_active) result = await SubjectService.get_subjects(is_active=is_active)
return success_response(data=result) return success_response(data=result)
except Exception as e:
logger.error(f"获取科目列表失败: {e}", exc_info=True)
return error_response(message=f"获取科目列表失败: {str(e)}", code=500)
@router.post("/create") @router.post("/create")
async def create_subject(request: Request, req: CreateSubjectRequest): async def create_subject(request: Request, req: CreateSubjectRequest):