mirror of
https://github.com/sprockets/sprockets.mixins.mediatype.git
synced 2024-11-21 11:18:36 +00:00
Gracefully handle transcoder encoding failures.
Since the form encoder refuses to handle nested sequences, the content mixin explicitly handles this case instead of letting the unhandled exception bubble up.
This commit is contained in:
parent
2df3aade3c
commit
1fe22df719
3 changed files with 43 additions and 5 deletions
|
@ -9,6 +9,8 @@ Version History
|
|||
and there is no default content type configured
|
||||
- Deprecate not having a default content type configured
|
||||
- Fail gracefully when a transcoder does not exist for the default content type
|
||||
- Fail gracefully when a transcoder raises a :exc:`TypeError` or :exc:`ValueError` when encoding
|
||||
the response
|
||||
|
||||
.. _application/x-www-formurlencoded: https://url.spec.whatwg.org/#application/x-www-form-urlencoded
|
||||
|
||||
|
|
|
@ -423,8 +423,15 @@ class ContentMixin(web.RequestHandler):
|
|||
settings.default_content_type)
|
||||
raise web.HTTPError(500)
|
||||
else:
|
||||
content_type, data_bytes = handler.to_bytes(body)
|
||||
if set_content_type:
|
||||
self.set_header('Content-Type', content_type)
|
||||
self.add_header('Vary', 'Accept')
|
||||
self.write(data_bytes)
|
||||
try:
|
||||
content_type, data_bytes = handler.to_bytes(body)
|
||||
except (TypeError, ValueError) as e:
|
||||
self._logger.error(
|
||||
'selected transcoder (%s) failed to encode response '
|
||||
'body: %s', handler.__class__.__name__, e)
|
||||
raise web.HTTPError(500, reason='Response Encoding Failure')
|
||||
else:
|
||||
if set_content_type:
|
||||
self.set_header('Content-Type', content_type)
|
||||
self.add_header('Vary', 'Accept')
|
||||
self.write(data_bytes)
|
||||
|
|
29
tests.py
29
tests.py
|
@ -177,6 +177,35 @@ class SendResponseTests(testing.AsyncHTTPTestCase):
|
|||
self.assertEqual('application/foo+json',
|
||||
response.headers.get('Content-Type'))
|
||||
|
||||
def test_that_transcoder_failures_result_in_500(self):
|
||||
class FailingTranscoder:
|
||||
content_type = 'application/vnd.com.example.bad'
|
||||
|
||||
def __init__(self):
|
||||
self.exc_class = TypeError
|
||||
|
||||
def to_bytes(self, inst_data, encoding=None):
|
||||
raise self.exc_class('I always fail at this')
|
||||
|
||||
def from_bytes(self, data_bytes, encoding=None):
|
||||
return {}
|
||||
|
||||
transcoder = FailingTranscoder()
|
||||
content.add_transcoder(self.application, transcoder)
|
||||
for _ in range(2):
|
||||
response = self.fetch(
|
||||
'/',
|
||||
method='POST',
|
||||
body=b'{}',
|
||||
headers={
|
||||
'Accept': 'application/vnd.com.example.bad',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
)
|
||||
self.assertEqual(500, response.code)
|
||||
self.assertEqual('Response Encoding Failure', response.reason)
|
||||
transcoder.exc_class = ValueError
|
||||
|
||||
|
||||
class GetRequestBodyTests(testing.AsyncHTTPTestCase):
|
||||
def setUp(self):
|
||||
|
|
Loading…
Reference in a new issue