优化商家订单详情接口500错误
This commit is contained in:
@@ -1,32 +1,33 @@
|
||||
# /opt/1panel/apps/openresty/nginx/www/sites/43.142.166.152.443/django/utils/exception_handler.py
|
||||
|
||||
from rest_framework.views import exception_handler
|
||||
from rest_framework.response import Response
|
||||
from rest_framework import status
|
||||
import logging
|
||||
import os
|
||||
import traceback
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
logger = logging.getLogger('django.request')
|
||||
|
||||
logger = logging.getLogger('django')
|
||||
|
||||
def custom_exception_handler(exc, context):
|
||||
"""
|
||||
生产环境安全异常处理器 - 不泄露任何敏感信息
|
||||
基于你之前项目的代码,做了小优化
|
||||
统一异常处理:所有错误写入终端日志(logger),生产环境响应不泄露细节。
|
||||
"""
|
||||
# 先调用默认异常处理器
|
||||
response = exception_handler(exc, context)
|
||||
|
||||
request = context.get('request')
|
||||
path = getattr(request, 'path', 'unknown')
|
||||
method = getattr(request, 'method', 'unknown')
|
||||
user = request.user if request else None
|
||||
user_info = f"用户: {user.id if user and user.is_authenticated else '未登录'}"
|
||||
|
||||
if response is not None:
|
||||
# 🔥 记录原始错误信息到日志(便于排查)
|
||||
request = context['request']
|
||||
user_info = f"用户: {request.user.id if request.user.is_authenticated else '未登录'}"
|
||||
logger.error(
|
||||
f"API异常 - 路径: {request.path}, "
|
||||
f"方法: {request.method}, {user_info}, "
|
||||
f"状态码: {response.status_code}, 错误: {str(exc)}"
|
||||
'API异常 path=%s method=%s %s status=%s error=%s',
|
||||
path, method, user_info, response.status_code, exc,
|
||||
exc_info=exc,
|
||||
)
|
||||
|
||||
# 🔥 生产环境返回标准化错误,不暴露任何细节
|
||||
if settings.DEBUG:
|
||||
return response
|
||||
error_messages = {
|
||||
status.HTTP_400_BAD_REQUEST: {'code': 400, 'message': '请求参数错误'},
|
||||
status.HTTP_401_UNAUTHORIZED: {'code': 401, 'message': '请先登录'},
|
||||
@@ -40,19 +41,27 @@ def custom_exception_handler(exc, context):
|
||||
status.HTTP_503_SERVICE_UNAVAILABLE: {'code': 503, 'message': '服务暂不可用'},
|
||||
status.HTTP_504_GATEWAY_TIMEOUT: {'code': 504, 'message': '网关超时'},
|
||||
}
|
||||
|
||||
# 🔥 如果是调试模式,返回详细错误(便于开发)
|
||||
from django.conf import settings
|
||||
if settings.DEBUG:
|
||||
return response
|
||||
|
||||
# 🔥 生产环境返回标准错误
|
||||
standard_response = error_messages.get(
|
||||
response.status_code,
|
||||
{'code': response.status_code, 'message': '请求错误'}
|
||||
response.status_code,
|
||||
{'code': response.status_code, 'message': '请求错误'},
|
||||
)
|
||||
|
||||
return Response(standard_response, status=response.status_code)
|
||||
|
||||
# 对于非DRF异常,这里可以根据需要处理
|
||||
return response
|
||||
|
||||
# DRF 未处理的异常(数据库字段缺失、AttributeError 等)→ 500 且无日志是常见问题
|
||||
logger.error(
|
||||
'未处理API异常 path=%s method=%s %s error=%s traceback=%s',
|
||||
path,
|
||||
method,
|
||||
user_info,
|
||||
exc,
|
||||
traceback.format_exc(),
|
||||
)
|
||||
if settings.DEBUG:
|
||||
return Response(
|
||||
{'code': 500, 'message': str(exc), 'detail': traceback.format_exc()},
|
||||
status=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
)
|
||||
return Response(
|
||||
{'code': 500, 'message': '服务器内部错误'},
|
||||
status=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user