58 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
			
		
		
	
	
			58 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
import traceback
 | 
						|
 | 
						|
from django.core.exceptions import PermissionDenied, ValidationError
 | 
						|
from django.http import Http404
 | 
						|
import logging
 | 
						|
from rest_framework import exceptions
 | 
						|
from rest_framework.response import Response
 | 
						|
from rest_framework.views import set_rollback
 | 
						|
import json
 | 
						|
from apps.utils.tasks import send_mail_task
 | 
						|
from django.conf import settings
 | 
						|
 | 
						|
 | 
						|
# 实例化myLogger
 | 
						|
myLogger = logging.getLogger('log')
 | 
						|
 | 
						|
 | 
						|
def custom_exception_hander(exc, context):
 | 
						|
    """
 | 
						|
    自定义异常处理
 | 
						|
    """
 | 
						|
    if isinstance(exc, Http404):
 | 
						|
        exc = exceptions.NotFound()
 | 
						|
    elif isinstance(exc, PermissionDenied):
 | 
						|
        exc = exceptions.PermissionDenied()
 | 
						|
    elif isinstance(exc, ValidationError):
 | 
						|
        exc = exceptions.ValidationError(exc.message)
 | 
						|
 | 
						|
    request_id = getattr(context['request'], 'request_id', None)
 | 
						|
    if isinstance(exc, exceptions.APIException):
 | 
						|
        headers = {}
 | 
						|
        if getattr(exc, 'auth_header', None):
 | 
						|
            headers['WWW-Authenticate'] = exc.auth_header
 | 
						|
        if getattr(exc, 'wait', None):
 | 
						|
            headers['Retry-After'] = '%d' % exc.wait
 | 
						|
        data = {'err_detail': exc.detail}
 | 
						|
        if isinstance(exc.detail, dict):
 | 
						|
            data['err_code'] = exc.default_code
 | 
						|
            data['err_msg'] = json.dumps(exc.detail, ensure_ascii=False) if 'detail' not in exc.detail else exc.detail['detail']  # 取一部分方便前端alert
 | 
						|
        elif isinstance(exc.detail, list):
 | 
						|
            data['err_code'] = exc.default_code
 | 
						|
            data['err_msg'] = json.dumps(exc.detail, ensure_ascii=False)
 | 
						|
        else:
 | 
						|
            data = {'err_msg': exc.detail, 'err_code': exc.get_codes()}
 | 
						|
 | 
						|
        set_rollback()
 | 
						|
        data['request_id'] = request_id
 | 
						|
        status = exc.status_code
 | 
						|
        if status not in [401, 404]:
 | 
						|
            status = 400
 | 
						|
        return Response(data, status=status, headers=headers)
 | 
						|
    args = (request_id, traceback.format_exc())
 | 
						|
    err_detail = f"{args[0]}-{args[1]}"
 | 
						|
    myLogger.error(err_detail)
 | 
						|
    if settings.DEBUG is False:
 | 
						|
        send_mail_task.delay(message=err_detail)  # 500邮件通知到开发人员
 | 
						|
    return Response(data={'err_code': 'server_error', 'err_detail': err_detail if settings.DEBUG else None, 'err_msg': '服务器错误'}, status=500)
 |