Skip to content

Commit 97d8484

Browse files
ticosaxtomchristie
authored andcommitted
Fix support of get_full_details() for Throttled exceptions (encode#4627)
Since `str` objects are immutable, appending to existing `str` creates in fact a new `str` instance. Thus `ErrorDetail.detail.code` attribute is lost after `str` concatenation operation.
1 parent 98df932 commit 97d8484

File tree

2 files changed

+29
-11
lines changed

2 files changed

+29
-11
lines changed

rest_framework/exceptions.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -210,14 +210,14 @@ class Throttled(APIException):
210210
default_code = 'throttled'
211211

212212
def __init__(self, wait=None, detail=None, code=None):
213+
if detail is None:
214+
detail = force_text(self.default_detail)
215+
if wait is not None:
216+
wait = math.ceil(wait)
217+
detail = ' '.join((
218+
detail,
219+
force_text(ungettext(self.extra_detail_singular.format(wait=wait),
220+
self.extra_detail_plural.format(wait=wait),
221+
wait))))
222+
self.wait = wait
213223
super(Throttled, self).__init__(detail, code)
214-
215-
if wait is None:
216-
self.wait = None
217-
else:
218-
self.wait = math.ceil(wait)
219-
self.detail += ' ' + force_text(ungettext(
220-
self.extra_detail_singular.format(wait=self.wait),
221-
self.extra_detail_plural.format(wait=self.wait),
222-
self.wait
223-
))

tests/test_exceptions.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
from __future__ import unicode_literals
22

33
from django.test import TestCase
4+
from django.utils import six
45
from django.utils.translation import ugettext_lazy as _
56

6-
from rest_framework.exceptions import ErrorDetail, _get_error_details
7+
from rest_framework.exceptions import (
8+
ErrorDetail, Throttled, _get_error_details
9+
)
710

811

912
class ExceptionTestCase(TestCase):
@@ -39,3 +42,18 @@ def test_get_error_details(self):
3942
_get_error_details([[lazy_example]])[0][0],
4043
ErrorDetail
4144
)
45+
46+
def test_get_full_details_with_throttling(self):
47+
exception = Throttled()
48+
assert exception.get_full_details() == {
49+
'message': 'Request was throttled.', 'code': 'throttled'}
50+
51+
exception = Throttled(wait=2)
52+
assert exception.get_full_details() == {
53+
'message': 'Request was throttled. Expected available in {} seconds.'.format(2 if six.PY3 else 2.),
54+
'code': 'throttled'}
55+
56+
exception = Throttled(wait=2, detail='Slow down!')
57+
assert exception.get_full_details() == {
58+
'message': 'Slow down! Expected available in {} seconds.'.format(2 if six.PY3 else 2.),
59+
'code': 'throttled'}

0 commit comments

Comments
 (0)