TIL62 - APIException

Kiyong Lee·2022년 2월 6일
1

DRF

목록 보기
2/3

APIException

우선, 모든 출처는 DRF공식문서이다.


기존에 했던 예외처리 방식

위코드에서 배울 때, 예외처리는 views.py에서 다 해줬었다.

def post(self,request,*args,**kwrags):
    try:
    
    except KeyError:
        return JsonResponse()

DRF의 예외처리

회사에서는 DRF를 사용하다보니, 최근 포스팅에서 언급한 APIView를 쓰며 APIException도 사용해서
공부하고 있었다.


우선, DRF의 Exception에 대해 알아보자

  • Exceptions
    프로그램 구조에서 오류 처리를 깔끔하게 구성할 수 있게 해준다

REST Frameworkview는 다양한 예외를 핸들링 할 수 있다.
그리고 에러에 대해 적절한 응답을 리턴할 수 있다.

처리된 예외는 다음과 같다.

  1. REST Framework 내부에서 발생한 APIException의 서브 클래스
  2. DjangoHttp404
  3. DjangoPermissionDenied

각 케이스마다, REST Framework는 적절한 응답코드와 타입을 리턴한다.

ResponseBody는 에러에 대해 detail도 포함하고 있다.

무슨 말이냐면, 대부분의 에러 응답은 ResponseBody안에 detail이라는 Key가 있다.


예를 들어, 아래와 같은 Endpoint로 요청을 보냈다고 가정해보자

DELETE http://localhost:8000/foo/bar

이 때 에러가 났다면,

{"detail" : "Method 'DELETE' not allowed."}

detail이라는 이름을 가진 에러 메시지가 리턴된다는 뜻이다.


단, Validation Error의 경우는 약간 다르다.

{"amount" : ["A valid interger is required,"], "Description":["This field may not be blank."] }

이렇게 문제가 발생한 컬럼과 메시지가 리턴된다.


에러 메시지 커스터마이징

detail이 메시지에 포함되어 나오는데, 커스터마이징도 가능하다.

from rest_framework.views import exception_handler

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)

    # Now add the HTTP status code to the response.
    if response is not None:
        response.data['status_code'] = response.status_code

    return response

이렇게 status_code를 리턴할 수 있도록 추가해준다면

{"status_code": 405, "detail": "Method 'DELETE' not allowed."}

이렇게 커스터마이징 할 수 있다.

Exception에 대해 커스터마이징을 하려면, 단순히 코드를 바꾸는 것 뿐만 아니라 settings.py에 추가해야 한다.

REST_FRAMEWORK = {
    'EXCEPTION_HANDLER' : 'my_project.my_app.utis.cumstom_exception_handler'
}

APIException

우선, 모든 exceptionsAPIView에서 발생한다.

커스터마이징하기 위해,
APIException서브클래스에 있는 .status_code, .default_detail, defailt_code를 세팅해야 한다.


예를 들어,

from rest_framework.exceptions import APIException

class ServiceUnavailable(APIException):
    status_code = 503
    default_detail = 'Service temporarily unavailable, try again later.'
    default_code = 'service_unavailable'

이렇게 설정을 해준 뒤, EXCEPTION_HANDLER에서 설정해준다면 내가 원하는 에러 메시지 핸들링이 된다.


다음 포스팅은 경쟁조건과 트랜잭션에 대한 거로 써볼 예정

profile
ISTJ인 K-개발자

0개의 댓글