[Django] DRF custom exception handling

1. The default exception handling

DRF has its own exception capture mechanism, which can capture APIException, Http404, PermissionDenied and other exceptions. The
processing function is located in rest_framework.views.exception_handler. Below is its source code.

def exception_handler(exc, context):
	...
    if isinstance(exc, Http404):
        exc = exceptions.NotFound()
    elif isinstance(exc, PermissionDenied):
        exc = exceptions.PermissionDenied()

    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

        if isinstance(exc.detail, (list, dict)):
            data = exc.detail
        else:
            data = {
    
    'detail': exc.detail}

        set_rollback()
        return Response(data, status=exc.status_code, headers=headers)

    return None

2. Custom exception handling

Because DRF's default exception handling function cannot meet other exception handling of the project, we need to customize it, that is, re-exception_handler() method

Create a new py file, define an exception_handler() method, copy the default source code of DRF, modify it, let it be processed in the default processing method first, if we can’t deal with it, we will use our own way, if it still can’t be processed, then return None

BooksTest/exceptions.py

def exception_handler(exc, context):
    # 处理得了返回一个响应,处理不了返回None
    
    # 1、把异常对象交给DRF的异常处理函数去处理
    response = drf_exception_handler(exc, context)
    if response:
        # response不为None,说明drf自行处理异常
        return response

    # 2、如果DRF异常处理函数无法处理,我们自行处理,例如处理除数为零的异常、数据库错误的异常等
    if isinstance(exc, ZeroDivisionError):
        return Response({
    
    'errmsg': '除数不能为零'})
    if isinstance(exc, DatabaseError):
        return Response({
    
    'errmsg': '数据库错误!'})

    return None

Although we wrote exception_handler(), Django doesn’t know it, so we have to specify to use it instead of the default handler

settings.py

REST_FRAMEWORK = {
    
    
    # ......
    # 自定义异常处理函数的导包路径
    'EXCEPTION_HANDLER': 'BooksTest.exceptions.exception_handler',
}

Guess you like

Origin blog.csdn.net/qq_39147299/article/details/108772941