44import traceback
55
66from django .conf import settings
7- from django .core .exceptions import PermissionDenied as _PermissionDenied , PermissionDenied
8- from django .http import Http404
9- from rest_framework import exceptions , status
107from rest_framework .response import Response
11- from rest_framework .status import HTTP_200_OK , HTTP_500_INTERNAL_SERVER_ERROR
12- from rest_framework .utils .serializer_helpers import ReturnList
13- from rest_framework .views import set_rollback
8+ from rest_framework .status import HTTP_500_INTERNAL_SERVER_ERROR
9+ from rest_framework .views import set_rollback , exception_handler
1410
1511
1612def _get_detail (detail ):
@@ -22,85 +18,17 @@ def _get_detail(detail):
2218 return result
2319
2420
25- class BaseError (Exception ):
26- code = HTTP_500_INTERNAL_SERVER_ERROR
27- params = None
28- message = 'internal error'
29-
30- def __init__ (self , message = None , detail = None , data = None ):
31- self .message = message or self .message
32- super ().__init__ (self .message , self .code , self .params )
33-
34-
35- def exception_handler (exc , context ):
36- """
37- Returns the response that should be used for any given exception.
38-
39- By default we handle the REST framework `APIException`, and also
40- Django's built-in `Http404` and `PermissionDenied` exceptions.
41-
42- Any unhandled exceptions may return `None`, which will cause a 500 error
43- to be raised.
44- """
45- if isinstance (exc , Http404 ):
46- exc = exceptions .NotFound ()
47- elif isinstance (exc , _PermissionDenied ):
48- exc = exceptions .PermissionDenied ()
49-
50- headers = {}
51- if isinstance (exc , exceptions .ValidationError ):
52- data = {"code" : exc .status_code , 'message' : exc .default_code , 'data' : exc .detail }
53- elif isinstance (exc , exceptions .APIException ):
54- # DRF异常处理
55- code = exc .status_code
56- if getattr (exc , 'auth_header' , None ):
57- headers ['WWW-Authenticate' ] = exc .auth_header
58- if getattr (exc , 'wait' , None ):
59- headers ['Retry-After' ] = '%d' % exc .wait
60- data = {"code" : code , 'message' : str (exc .detail ), 'data' : exc .detail }
61- elif isinstance (exc , BaseError ):
62- # 自定义异常处理
63- data = {"code" : exc .code , "message" : exc .message }
64- else :
65- data = {"code" : HTTP_500_INTERNAL_SERVER_ERROR , "message" : "Internal Error" , "data" : getattr (exc , 'message' , repr (exc ))}
66-
67- set_rollback ()
68- if settings .DEBUG :
69- traceback .print_exc ()
70- data .update (traceback = traceback .format_exc ())
71- return Response (data , status = HTTP_200_OK , headers = headers )
72-
73-
74- def exception_handler (exc , context ):
75- """
76- Returns the response that should be used for any given exception.
77-
78- By default we handle the REST framework `APIException`, and also
79- Django's built-in `Http404` and `PermissionDenied` exceptions.
80-
81- Any unhandled exceptions may return `None`, which will cause a 500 error
82- to be raised.
83- """
84- if isinstance (exc , Http404 ):
85- exc = exceptions .NotFound ()
86- elif isinstance (exc , PermissionDenied ):
87- exc = exceptions .PermissionDenied ()
88-
89- if isinstance (exc , exceptions .APIException ):
90- headers = {}
91- if getattr (exc , 'auth_header' , None ):
92- headers ['WWW-Authenticate' ] = exc .auth_header
93- if getattr (exc , 'wait' , None ):
94- headers ['Retry-After' ] = '%d' % exc .wait
95-
96- if isinstance (exc .detail , (list , dict )):
97- data = exc .detail
98- else :
99- data = {'detail' : exc .detail }
21+ def custom_exception_handler (exc , context ):
22+ # Call REST framework's default exception handler first,
23+ # to get the standard error response.
24+ response = exception_handler (exc , context )
10025
26+ # Catch other exceptions.
27+ if response is None :
28+ response = Response ({"detail" : str (exc )}, status = HTTP_500_INTERNAL_SERVER_ERROR )
10129 set_rollback ()
102- resp = Response ( data , status = status . HTTP_200_OK , headers = headers )
103- resp . error_code = exc . status_code
104- return resp
30+ if settings . DEBUG :
31+ traceback . print_exc ()
32+ response . data . update ( traceback = traceback . format_exc ())
10533
106- return None
34+ return response
0 commit comments