DRf, handle unhandled exception

2019-08-03 09:49发布

问题:

When using DRF, Django's ValueError (django.core.exceptions) and IntegrityError (django.db) is not handled.

DRF's def exception_handler has exception handling code for (APIException, Http404, PermissionDenied)

Below is a code for Http404

 elif isinstance(exc, Http404):
     msg = _('Not found.')
     data = {'detail': six.text_type(msg)}

     set_rollback()
     return Response(data, status=status.HTTP_404_NOT_FOUND)

So I can create my custom exception handler as

 def custom_exception_handler(exc, context):
     # Call REST framework's default exception handler first,
     # to get the standard error response.
     response = exception_handler(exc, context)

     if isinstance(exc, ValidationError) or isinstance(exc, IntegrityError):
         data = {
             'errors': str(exc)
         }
         set_rollback()   # not sure about this line
         response = Response(data, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

     return response

I'm not sure about the purpose of set_rollback() line in the code, and not sure if I'm safe with this code.

回答1:

The reason that IntegrityError and ValueError aren't handled by default in DRF is because they need to be handled in a case by case basis. So writing a generic exception handler like what you are trying to do here probably isn't the right way.

For example, some IntegrityErrors can probably be just ignored, but some like that happens in the middle of a fund transfer cannot be. So better to try something like this:

def create(self, request):
    try :
        return super(MyViewSet, self).create(request)
    except IntergrityError:
        # your decision here how to handle it.
        raise APIException(detail='Custom message')