Last active
May 12, 2019 06:35
-
-
Save harunurkst/8b1b0db9bdff3ce8a07819669299cb02 to your computer and use it in GitHub Desktop.
Custom exception handler for Django rest framework
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from rest_framework.exceptions import ErrorDetail | |
def format_code(code_name): | |
"""Format django error code to Circle Error code""" | |
if code_name == 'blank': | |
return "BLANK_FIELD" | |
elif code_name == 'invalid': | |
return "INVALID_DATA" | |
elif code_name == 'required': | |
return "KEY_ERROR" | |
else: | |
return "INVALID_DATA" | |
def find_error_code(response_data): | |
""" | |
A custom function to get error code (i.e: invalid, blank) | |
if error in single item dict like : {'name':''}, error response would | |
{'name': [ErrorDetail(string='This field may not be blank.', code='blank')]} | |
:param response_data: {'accounts': [{}, | |
{'nominee_info': | |
{'name': [ErrorDetail(string='This field may not be blank.', code='blank')]}, | |
'account_type': [ErrorDetail(string='This field may not be blank.', code='blank')]}] | |
} | |
:return: ERROR_CODE | |
""" | |
for field, value in response_data.items(): | |
# if value is a list | |
if isinstance(value, list): | |
for item in value: | |
# if item is ErrorDetail object | |
if isinstance(item, ErrorDetail): | |
code = getattr(item, 'code', None) | |
return format_code(code) | |
elif isinstance(item, dict): | |
if any(item): | |
# If dictionary is not blank | |
# recursive function call with item data | |
return find_error_code(item) | |
else: | |
# if dictionay is blank, continue to next item | |
continue | |
else: | |
# call function again, until value is list (or [ErrorDetail obj]) | |
return find_error_code(value) | |
def custom_exception_handler(exc, context): | |
''' | |
Override drf default validation error message response and sends as a list | |
:param exc: | |
:param context: | |
:return: response obj | |
''' | |
response = exception_handler(exc, context) | |
if isinstance(exc.detail, (list, dict)): | |
err_code = find_error_code(response.data) | |
response.data.clear() | |
response.data['error_code'] = err_code | |
return response | |
else: | |
response.data.clear() | |
response.data['error_code'] = exc.detail | |
return response | |
""" | |
# to work with this custome error handler, save this file in your project, | |
#add this in settings.py | |
REST_FRAMEWORK = { | |
'EXCEPTION_HANDLER': 'clibs.c_exceptions.custom_exception_handler', #location for your file | |
} | |
# and add raise_exception=True in is_valid() method | |
if serializer.is_valid(raise_exception=True): | |
""" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment