1- from django .utils import encoding
1+ import inspect
2+ from django .utils import six , encoding
23from django .utils .translation import ugettext_lazy as _
3- from rest_framework import status
4- from rest_framework .exceptions import APIException
4+ from rest_framework import status , exceptions
55from rest_framework .views import exception_handler as drf_exception_handler
66
77from rest_framework_json_api .utils import format_value
@@ -32,11 +32,17 @@ def exception_handler(exc, context):
3232 # see if they passed a dictionary to ValidationError manually
3333 if isinstance (error , dict ):
3434 errors .append (error )
35- # or a string in case of AuthenticationError
36- elif isinstance (error , str ):
37- # An error MUST be a JSON object in JSON API spec
35+ elif isinstance (error , six .string_types ):
36+ classes = inspect .getmembers (exceptions , inspect .isclass )
37+ # DRF sets the `field` to 'detail' for its own exceptions
38+ if isinstance (exc , tuple (x [1 ] for x in classes )):
39+ pointer = '/data'
3840 errors .append ({
39- 'detail' : error
41+ 'detail' : error ,
42+ 'source' : {
43+ 'pointer' : pointer ,
44+ },
45+ 'status' : encoding .force_text (response .status_code ),
4046 })
4147 elif isinstance (error , list ):
4248 for message in error :
@@ -49,7 +55,7 @@ def exception_handler(exc, context):
4955 })
5056 else :
5157 errors .append ({
52- 'detail' : message ,
58+ 'detail' : error ,
5359 'source' : {
5460 'pointer' : pointer ,
5561 },
@@ -62,6 +68,7 @@ def exception_handler(exc, context):
6268 return response
6369
6470
65- class Conflict (APIException ):
71+ class Conflict (exceptions . APIException ):
6672 status_code = status .HTTP_409_CONFLICT
6773 default_detail = _ ('Conflict.' )
74+
0 commit comments