Django

[Django] Custom Exception Handler

torimuk 2022. 9. 29. 15:33

Problem


예기치 못한 Exception이 발생했을 때, 이를 감지할 수 있는 시스템이 필요했다.

기존에는 Exception Handler View를 만들어 로직을 처리한 후 template을 return 했지만, DRF API로 변환하면서 해당 기능의 수정이 필요해졌다.

Exception Handler View 포스트

 

[Django] 500 Internal server error handler

Problem http 500 서버 에러 발생 시의 처리 로직을 구현. Solution 이미 구현되어 있는 django.conf.urls.handler500 을 이용한다. django.conf.urls.handler500 에 view의 함수를 지정해주고, view에서 에러 관..

torimuk.tistory.com

 

Solution


1. Exception 을 처리할 함수를 만들어준다.

def custom_exception_handler(exc, context):
    pass

2. DRF에 내장되어있는 exception_handler를 import한다.

from rest_framework.views import exception_handler

3. DRF의 exception_handler를 통해 받아들여온 response와 exc, context를 활용해 코드를 작성한다. 

필자는 예기치 않은 오류가 발생해 response를 넘기지 못했을 때 감지하여 슬랙 봇을 통해 나의 슬랙으로

송신하는 코드를 작성하였다.

def custom_exception_handler(exc, context):
    response = exception_handler(exc, context)
    request = context.get('request')

    if response is None:
        res = response_object()		# 임의로 만든 response 객체
        unauthorized = res.check_authorized(request.META)	# request 유저가 인가된 유저인지 확인

        if unauthorized:
            username = "unknown"
        else:
            token = res.get_token()							# JWT 토큰
            username = token.get("admin_id")

        cur_time = get_current_time()
        setting_value = str(settings).split('"')[-2]  # settings 값을 문자열로 읽어옴
        target = setting_value.split(".")[-1]  # settings 파일

        err_str = traceback.format_exc()					# 발생한 error traceback.
        msg = "===========================================================================\n"
        msg += f"*[{target} server 에러 발생]*\n>*유저*: {username}\n>*발생 일시*: {cur_time}\n\n*에러 코드*```{request.method} {request.path_info}\n\n{err_str}```\n"

        data = {
            'token': CONST.SLACK_TOKEN,
            'channel': CONST.SLACK_CHANNEL,
            'as_user': True,
            'text': msg,
        }
        requests.post(url='https://slack.com/api/chat.postMessage', data=data)		# 나의 슬랙 봇으로 송신

4. 설정 파일에서 DRF exception_handler 관련 설정을 추가해준다.

REST_FRAMEWORK = {
    "EXCEPTION_HANDLER": "admin_api.exception.custom_exception_handler",
}

5. 추가적으로 response 에 지정한 데이터를 추가하거나 수정하여 송신할 수 있다. exception_handler(exc, context) 에서 반환된 response를 수정하면 가능하다.

URL


 

https://www.django-rest-framework.org/api-guide/exceptions/#custom-exception-handling