diff --git a/docs/api-guide/exceptions.md b/docs/api-guide/exceptions.md index 467ad9709..31a8431bc 100644 --- a/docs/api-guide/exceptions.md +++ b/docs/api-guide/exceptions.md @@ -51,10 +51,10 @@ In order to alter the style of the response, you could write the following custo from rest_framework.views import exception_handler - def custom_exception_handler(exc): + def custom_exception_handler(exc, context): # Call REST framework's default exception handler first, # to get the standard error response. - response = exception_handler(exc) + response = exception_handler(exc, context) # Now add the HTTP status code to the response. if response is not None: diff --git a/docs/api-guide/settings.md b/docs/api-guide/settings.md index 9005511b7..2c4f84237 100644 --- a/docs/api-guide/settings.md +++ b/docs/api-guide/settings.md @@ -393,7 +393,7 @@ This setting can be changed to support error responses other than the default `{ This should be a function with the following signature: - exception_handler(exc) + exception_handler(exc, context) * `exc`: The exception. diff --git a/rest_framework/views.py b/rest_framework/views.py index bc870417f..b39724c2f 100644 --- a/rest_framework/views.py +++ b/rest_framework/views.py @@ -2,6 +2,8 @@ Provides an APIView class that is the base of all views in REST framework. """ from __future__ import unicode_literals +import inspect +import warnings from django.core.exceptions import PermissionDenied from django.http import Http404 @@ -46,7 +48,7 @@ def get_view_description(view_cls, html=False): return description -def exception_handler(exc): +def exception_handler(exc, context): """ Returns the response that should be used for any given exception. @@ -184,6 +186,18 @@ class APIView(View): 'request': getattr(self, 'request', None) } + def get_exception_handler_context(self): + """ + Returns a dict that is passed through to EXCEPTION_HANDLER, + as the `context` argument. + """ + return { + 'view': self, + 'args': getattr(self, 'args', ()), + 'kwargs': getattr(self, 'kwargs', {}), + 'request': getattr(self, 'request', None) + } + def get_view_name(self): """ Return the view name, as used in OPTIONS responses and in the @@ -369,7 +383,18 @@ class APIView(View): else: exc.status_code = status.HTTP_403_FORBIDDEN - response = self.settings.EXCEPTION_HANDLER(exc) + exception_handler = self.settings.EXCEPTION_HANDLER + + if len(inspect.getargspec(exception_handler).args) == 1: + warnings.warn( + 'The `exception_handler(exc)` call signature is deprecated. ' + 'Use `exception_handler(exc, context) instead.', + PendingDeprecationWarning + ) + response = exception_handler(exc) + else: + context = self.get_exception_handler_context() + response = exception_handler(exc, context) if response is None: raise