Last active
October 6, 2019 07:49
-
-
Save zarinpy/6db48ac4d342a20d5d127051251ed071 to your computer and use it in GitHub Desktop.
custom exception ahndler 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.views import exception_handler | |
from rest_framework.exceptions import ErrorDetail | |
def custom_exception_handler(exc, context): | |
if hasattr(exc, 'detail'): | |
if isinstance(exc.detail, ErrorDetail): | |
context['kwargs']['message'] = exc.detail.title() | |
else: | |
t = exc.get_full_details().popitem() | |
context['kwargs']['message'] = "input parameters are not valid." | |
context['kwargs']['exception'] = "{}: {}".format(t[0], t[1][0]['message'].title()) | |
context['kwargs']['code'] = exc.status_code | |
response = exception_handler(exc, context) | |
if hasattr(response, 'data'): | |
response.data = {} | |
return response |
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 __future__ import unicode_literals | |
from django.utils import six | |
from rest_framework.compat import ( | |
INDENT_SEPARATORS, LONG_SEPARATORS, SHORT_SEPARATORS | |
) | |
from rest_framework.renderers import JSONRenderer | |
from rest_framework.utils import json | |
def zero_as_none(value): | |
return None if value == 0 else value | |
class CustomRenderer(JSONRenderer): | |
def render(self, data, accepted_media_type=None, renderer_context=None): | |
if data is None: | |
return bytes() | |
renderer_context = renderer_context or {} | |
indent = self.get_indent(accepted_media_type, renderer_context) | |
new_data = { | |
'code': None, | |
'message': '', | |
'exception': '', | |
'data': {}, | |
} | |
if indent is None: | |
separators = SHORT_SEPARATORS if self.compact else LONG_SEPARATORS | |
else: | |
separators = INDENT_SEPARATORS | |
if 'code' in renderer_context['kwargs'].keys(): | |
new_data['code'] = renderer_context['kwargs']['code'] | |
else: | |
new_data['code'] = renderer_context['response'].status_code | |
if 'message' in renderer_context['kwargs'].keys(): | |
new_data['message'] = renderer_context['kwargs']['message'] | |
if 'exception' in renderer_context['kwargs'].keys(): | |
new_data['exception'] = renderer_context['kwargs']['exception'] | |
new_data['data'] = data | |
ret = json.dumps( | |
new_data, cls=self.encoder_class, | |
indent=indent, ensure_ascii=self.ensure_ascii, | |
allow_nan=not self.strict, separators=separators | |
) | |
if isinstance(ret, six.text_type): | |
ret = ret.replace('\u2028', '\\u2028').replace('\u2029', '\\u2029') | |
return bytes(ret.encode('utf-8')) | |
return ret |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
to design a good api we should consider many things.
imagine we should call a web service in our api and we should response it.
there are some conditions that should be covered in expose.
if our api works correctly but the web service has not and upside down.
this file can handle all the exception type that we should expose.
we can access the
kwargs
from view by this functionself.get_renderer_context()
and set kwargs likemessage
,code
andexception
.and this custom renderer can handle the expose