Skip to content

Allow exception handler to be used by normal DRF views #233

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 29, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 26 additions & 2 deletions rest_framework_json_api/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
from django.conf import settings
from django.utils.translation import ugettext_lazy as _
from rest_framework import status, exceptions

from rest_framework_json_api import utils
from rest_framework_json_api import renderers


def rendered_with_json_api(view):
for renderer_class in getattr(view, 'renderer_classes', []):
if issubclass(renderer_class, renderers.JSONRenderer):
return True
return False


def exception_handler(exc, context):
Expand All @@ -12,11 +21,26 @@ def exception_handler(exc, context):
#
# Also see: https://github.com/django-json-api/django-rest-framework-json-api/issues/158
from rest_framework.views import exception_handler as drf_exception_handler
response = drf_exception_handler(exc, context)

# Render exception with DRF
response = drf_exception_handler(exc, context)
if not response:
return response
return utils.format_drf_errors(response, context, exc)

# Use regular DRF format if not rendered by DRF JSON API and not uniform
is_json_api_view = rendered_with_json_api(context['view'])
is_uniform = getattr(settings, 'JSON_API_UNIFORM_EXCEPTIONS', False)
if not is_json_api_view and not is_uniform:
return response

# Convert to DRF JSON API error format
response = utils.format_drf_errors(response, context, exc)

# Add top-level 'errors' object when not rendered by DRF JSON API
if not is_json_api_view:
response.data = utils.format_errors(response.data)

return response


class Conflict(exceptions.APIException):
Expand Down
5 changes: 1 addition & 4 deletions rest_framework_json_api/renderers.py
Original file line number Diff line number Diff line change
Expand Up @@ -381,11 +381,8 @@ def render_relationship_view(self, data, accepted_media_type=None, renderer_cont
)

def render_errors(self, data, accepted_media_type=None, renderer_context=None):
# Get the resource name.
if len(data) > 1 and isinstance(data, list):
data.sort(key=lambda x: x.get('source', {}).get('pointer', ''))
return super(JSONRenderer, self).render(
{'errors': data}, accepted_media_type, renderer_context
utils.format_errors(data), accepted_media_type, renderer_context
)

def render(self, data, accepted_media_type=None, renderer_context=None):
Expand Down
7 changes: 7 additions & 0 deletions rest_framework_json_api/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,4 +315,11 @@ def format_drf_errors(response, context, exc):

context['view'].resource_name = 'errors'
response.data = errors

return response


def format_errors(data):
if len(data) > 1 and isinstance(data, list):
data.sort(key=lambda x: x.get('source', {}).get('pointer', ''))
return {'errors': data}