diff --git a/server/urls.py b/server/urls.py index cb74342..2efbedb 100644 --- a/server/urls.py +++ b/server/urls.py @@ -86,11 +86,54 @@ def auto_load_routers(package_name_prefix=None): class UnifiedNinjaAPI(NinjaExtraAPI): def create_response(self, request, data, *, status=None, headers=None, temporal_response=None): - if not isinstance(data, CommonResponse): - if isinstance(data, tuple) and len(data) == 2: - data, status = data - data = CommonResponse.success(data=data) - return super().create_response(request, data, status=status, temporal_response=temporal_response) + # 1. 如果已经是 CommonResponse,直接放行(避免递归) + if isinstance(data, CommonResponse): + return super().create_response(request, data, status=status, temporal_response=temporal_response) + + # 2. 处理 (data, status) 元组 + if isinstance(data, tuple) and len(data) == 2: + data, status = data + + # 3. 确保 status 有值,默认为 200 + if status is None: + status = 200 + + # ================= 核心修改开始 ================= + # 4. 嗅探数据内容:判断是否是框架抛出的异常数据 + # Django Ninja / DRF 的异常通常格式为 {"detail": "错误信息"} + # 或者 {"errors": [...]} + is_framework_error = False + error_message = "" + + if isinstance(data, dict): + # 情况 A: 捕获到 {"detail": "权限不足"} + if "detail" in data: + is_framework_error = True + error_message = data.get("detail") + # 情况 B: 捕获到其他标准错误格式 (可选) + elif "message" in data and status >= 400: + is_framework_error = True + error_message = data.get("message") + + # 5. 根据嗅探结果决定返回 success 还是 error + if is_framework_error: + # 强制返回 error 结构,succeed=False + # 注意:这里通常使用 403 或 500 作为 code,或者保留原始 status + return super().create_response( + request, + CommonResponse.error(code=status, data=data, msg=error_message), + status=status, + temporal_response=temporal_response + ) + + # 如果不是错误,继续正常的成功逻辑 + if 200 <= status < 300: + wrapped_data = CommonResponse.success(data=data) + else: + # 其他非 200 状态码视为业务错误 + wrapped_data = CommonResponse.error(code=status, data=data) + + return super().create_response(request, wrapped_data, status=status, temporal_response=temporal_response) api_v1 = UnifiedNinjaAPI(version='1.0.0', auth=JWTAuth())