Repository: encode/django-rest-framework

Issue:
Unhandled exception traceback hides exception original string on python 2.7
After commit e3686aca93a8224280b38b7669342bcadb24176e (3.5.1 version) python 2.7 traceback for unhandled exceptions no longer contain line where exception occured, because we're reraising exception explicitly.

```
  File "/Users/coagulant/.envs/myproject/lib/python2.7/site-packages/rest_framework/viewsets.py", line 83, in view
    return self.dispatch(request, *args, **kwargs)
  File "/Users/coagulant/.envs/myproject/lib/python2.7/site-packages/rest_framework/views.py", line 477, in dispatch
    response = self.handle_exception(exc)
  File "/Users/coagulant/.envs/myproject/lib/python2.7/site-packages/rest_framework/views.py", line 437, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/Users/coagulant/.envs/myproject/lib/python2.7/site-packages/rest_framework/views.py", line 448, in raise_uncaught_exception
    raise exc
KeyError: 'request'
```

Full tracebacks:

<details>
 <summary>

Traceback on DRF 3.5.0 (good behavior)</summary>



```
Traceback (most recent call last):
  File "/Users/coagulant/projects/myproject/project/tests/api/account_tests.py", line 346, in test_put_account_detail_restricted_fields_200
    {'email': u'some.unconfirmed@email.com'})
  File "/Users/coagulant/.envs/myproject/lib/python2.7/site-packages/rest_framework/test.py", line 307, in put
    path, data=data, format=format, content_type=content_type, **extra)
  File "/Users/coagulant/.envs/myproject/lib/python2.7/site-packages/rest_framework/test.py", line 225, in put
    return self.generic('PUT', path, data, content_type, **extra)
  File "/Users/coagulant/.envs/myproject/lib/python2.7/site-packages/django/test/client.py", line 380, in generic
    return self.request(**r)
  File "/Users/coagulant/projects/myproject/project/tests/fixtures/clients.py", line 27, in request
    return super(DRFAPIClient, self).request(**kwargs)
  File "/Users/coagulant/projects/myproject/project/tests/fixtures/clients.py", line 17, in request
    return super(AutoPrependBasePathMixin, self).request(**kwargs)
  File "/Users/coagulant/.envs/myproject/lib/python2.7/site-packages/rest_framework/test.py", line 288, in request
    return super(APIClient, self).request(**kwargs)
  File "/Users/coagulant/.envs/myproject/lib/python2.7/site-packages/rest_framework/test.py", line 240, in request
    request = super(APIRequestFactory, self).request(**kwargs)
  File "/Users/coagulant/.envs/myproject/lib/python2.7/site-packages/django/test/client.py", line 449, in request
    response = self.handler(environ)
  File "/Users/coagulant/.envs/myproject/lib/python2.7/site-packages/django/test/client.py", line 123, in __call__
    response = self.get_response(request)
  File "/Users/coagulant/.envs/myproject/lib/python2.7/site-packages/rest_framework/test.py", line 260, in get_response
    return super(ForceAuthClientHandler, self).get_response(request)
  File "/Users/coagulant/.envs/myproject/lib/python2.7/site-packages/django/core/handlers/base.py", line 230, in get_response
    response = self.handle_uncaught_exception(request, resolver, sys.exc_info())
  File "/Users/coagulant/.envs/myproject/lib/python2.7/site-packages/django/core/handlers/base.py", line 149, in get_response
    response = self.process_exception_by_middleware(e, request)
  File "/Users/coagulant/.envs/myproject/lib/python2.7/site-packages/django/core/handlers/base.py", line 147, in get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/Users/coagulant/.envs/myproject/lib/python2.7/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
    return view_func(*args, **kwargs)
  File "/Users/coagulant/.envs/myproject/lib/python2.7/site-packages/rest_framework/viewsets.py", line 83, in view
    return self.dispatch(request, *args, **kwargs)
  File "/Users/coagulant/.envs/myproject/lib/python2.7/site-packages/rest_framework/views.py", line 477, in dispatch
    response = self.handle_exception(exc)
  File "/Users/coagulant/.envs/myproject/lib/python2.7/site-packages/rest_framework/views.py", line 437, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/Users/coagulant/.envs/myproject/lib/python2.7/site-packages/rest_framework/views.py", line 474, in dispatch
    response = handler(request, *args, **kwargs)
  File "/Users/coagulant/.envs/myproject/lib/python2.7/site-packages/rest_framework/mixins.py", line 78, in update
    return Response(serializer.data)
  File "/Users/coagulant/.envs/myproject/lib/python2.7/site-packages/rest_framework/serializers.py", line 504, in data
    ret = super(Serializer, self).data
  File "/Users/coagulant/.envs/myproject/lib/python2.7/site-packages/rest_framework/serializers.py", line 239, in data
    self._data = self.to_representation(self.instance)
  File "/Users/coagulant/.envs/myproject/lib/python2.7/site-packages/rest_framework/serializers.py", line 473, in to_representation
    ret[field.field_name] = field.to_representation(attribute)
  File "/Users/coagulant/.envs/myproject/lib/python2.7/site-packages/rest_framework/relations.py", line 371, in to_representation
    url = self.get_url(value, self.view_name, request, format)
  File "/Users/coagulant/projects/myproject/project/api/serializers.py", line 19, in get_url
    version = kwargs['request'].version
KeyError: 'request'
```

</details>

<details>
 <summary>

Traceback on DRF 3.5.1 (unexpected behavior)</summary>



```
Traceback (most recent call last):
  File "/Users/coagulant/projects/myproject/project/tests/api/account_tests.py", line 346, in test_put_account_detail_restricted_fields_200
    {'email': u'some.unconfirmed@email.com'})
  File "/Users/coagulant/.envs/myproject/lib/python2.7/site-packages/rest_framework/test.py", line 307, in put
    path, data=data, format=format, content_type=content_type, **extra)
  File "/Users/coagulant/.envs/myproject/lib/python2.7/site-packages/rest_framework/test.py", line 225, in put
    return self.generic('PUT', path, data, content_type, **extra)
  File "/Users/coagulant/.envs/myproject/lib/python2.7/site-packages/django/test/client.py", line 380, in generic
    return self.request(**r)
  File "/Users/coagulant/projects/myproject/project/tests/fixtures/clients.py", line 27, in request
    return super(DRFAPIClient, self).request(**kwargs)
  File "/Users/coagulant/projects/myproject/project/tests/fixtures/clients.py", line 17, in request
    return super(AutoPrependBasePathMixin, self).request(**kwargs)
  File "/Users/coagulant/.envs/myproject/lib/python2.7/site-packages/rest_framework/test.py", line 288, in request
    return super(APIClient, self).request(**kwargs)
  File "/Users/coagulant/.envs/myproject/lib/python2.7/site-packages/rest_framework/test.py", line 240, in request
    request = super(APIRequestFactory, self).request(**kwargs)
  File "/Users/coagulant/.envs/myproject/lib/python2.7/site-packages/django/test/client.py", line 449, in request
    response = self.handler(environ)
  File "/Users/coagulant/.envs/myproject/lib/python2.7/site-packages/django/test/client.py", line 123, in __call__
    response = self.get_response(request)
  File "/Users/coagulant/.envs/myproject/lib/python2.7/site-packages/rest_framework/test.py", line 260, in get_response
    return super(ForceAuthClientHandler, self).get_response(request)
  File "/Users/coagulant/.envs/myproject/lib/python2.7/site-packages/django/core/handlers/base.py", line 230, in get_response
    response = self.handle_uncaught_exception(request, resolver, sys.exc_info())
  File "/Users/coagulant/.envs/myproject/lib/python2.7/site-packages/django/core/handlers/base.py", line 149, in get_response
    response = self.process_exception_by_middleware(e, request)
  File "/Users/coagulant/.envs/myproject/lib/python2.7/site-packages/django/core/handlers/base.py", line 147, in get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/Users/coagulant/.envs/myproject/lib/python2.7/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
    return view_func(*args, **kwargs)
  File "/Users/coagulant/.envs/myproject/lib/python2.7/site-packages/rest_framework/viewsets.py", line 83, in view
    return self.dispatch(request, *args, **kwargs)
  File "/Users/coagulant/.envs/myproject/lib/python2.7/site-packages/rest_framework/views.py", line 477, in dispatch
    response = self.handle_exception(exc)
  File "/Users/coagulant/.envs/myproject/lib/python2.7/site-packages/rest_framework/views.py", line 437, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/Users/coagulant/.envs/myproject/lib/python2.7/site-packages/rest_framework/views.py", line 448, in raise_uncaught_exception
    raise exc
KeyError: 'request'
```

</details>



Discussion:
Missed that line and agreed, raising should preserve the stack so it's either a raw raise or drf will have to backfeed the traceback

<details><summary>

Most of all what I've learned from this...</summary>

Is how to use `<details><summary>` in GitHub issues. 👍 </details>

Okay, so the change there was in response to https://github.com/tomchristie/django-rest-framework/pull/4600 "raise with no arguments can only be used in an except clause as of Python 3.5."

Any suggestions for how to proceed?

> Okay, so the change there was in response to #4600 "raise with no arguments can only be used in an except clause as of Python 3.5."
> Any suggestions for how to proceed?

I suppose handle_exception is called inside an except clause, and there was no problem in the first place?


Resolving patch:
diff --git a/rest_framework/views.py b/rest_framework/views.py
--- a/rest_framework/views.py
+++ b/rest_framework/views.py
@@ -445,7 +445,7 @@ def raise_uncaught_exception(self, exc):
             renderer_format = getattr(request.accepted_renderer, 'format')
             use_plaintext_traceback = renderer_format not in ('html', 'api', 'admin')
             request.force_plaintext_errors(use_plaintext_traceback)
-        raise exc
+        raise
 
     # Note: Views are made CSRF exempt from within `as_view` as to prevent
     # accidental removal of this exemption in cases where `dispatch` needs to


Test patch: