Permalink
Browse files

If JSON parsing fails it now issues a BadRequest exception.

  • Loading branch information...
1 parent acac64e commit ce701319756abef4d09c585828a630b8fdef89fc @mitsuhiko mitsuhiko committed Aug 8, 2011
Showing with 36 additions and 4 deletions.
  1. +4 −1 CHANGES
  2. +7 −0 docs/upgrading.rst
  3. +16 −3 flask/wrappers.py
  4. +9 −0 tests/flask_tests.py
View
@@ -14,7 +14,7 @@ Relase date to be decided, codename to be chosen.
- Empty session cookies are now deleted properly automatically.
- View functions can now opt out of getting the automatic
OPTIONS implementation.
-- HTTP exceptions and Bad Request Key Errors can now be trapped so that they
+- HTTP exceptions and Bad Request errors can now be trapped so that they
show up normally in the traceback.
- Flask in debug mode is now detecting some common problems and tries to
warn you about them.
@@ -23,6 +23,9 @@ Relase date to be decided, codename to be chosen.
feedback when users forget to import view code ahead of time.
- Added the ability to register callbacks that are only triggered once at
the beginning of the first request. (:meth:`Flask.before_first_request`)
+- Malformed JSON data will now trigger a bad request HTTP exception instead
+ of a value error which usually would result in a 500 internal server
+ error if not handled. This is a backwards incompatible change.
Version 0.7.3
-------------
View
@@ -29,6 +29,13 @@ object. With that introduction we moved the implementation details for
the session system into a new module called :mod:`flask.sessions`. If you
used the previously undocumented session support we urge you to upgrade.
+If invalid JSON data was submitted Flask will now raise a
+:exc:`~werkzeug.exceptions.BadRequest` exception instead of letting the
+default :exc:`ValueError` bubble up. This has the advantage that you no
+longer have to handle that error to avoid an internal server error showing
+up for the user. If you were catching this down explicitly in the past
+as `ValueError` you will need to change this.
+
Version 0.7
-----------
View
@@ -10,6 +10,7 @@
"""
from werkzeug.wrappers import Request as RequestBase, Response as ResponseBase
+from werkzeug.exceptions import BadRequest
from werkzeug.utils import cached_property
from .debughelpers import attach_enctype_error_multidict
@@ -96,9 +97,21 @@ def json(self):
_assert_have_json()
if self.mimetype == 'application/json':
request_charset = self.mimetype_params.get('charset')
- if request_charset is not None:
- return json.loads(self.data, encoding=request_charset)
- return json.loads(self.data)
+ try:
+ if request_charset is not None:
+ return json.loads(self.data, encoding=request_charset)
+ return json.loads(self.data)
+ except ValueError, e:
+ return self.on_json_loading_failed(e)
+
+ def on_json_loading_failed(self, e):
+ """Called if decoding of the JSON data failed. The return value of
+ this method is used by :attr:`json` when an error ocurred. The
+ default implementation raises a :class:`~werkzeug.exceptions.BadRequest`.
+
+ .. versionadded:: 0.8
+ """
+ raise BadRequest()
def _load_form_data(self):
RequestBase._load_form_data(self)
View
@@ -984,6 +984,15 @@ def foo():
class JSONTestCase(unittest.TestCase):
+ def test_json_bad_requests(self):
+ app = flask.Flask(__name__)
+ @app.route('/json', methods=['POST'])
+ def return_json():
+ return unicode(flask.request.json)
+ c = app.test_client()
+ rv = c.post('/json', data='malformed', content_type='application/json')
+ self.assertEqual(rv.status_code, 400)
+
def test_json_body_encoding(self):
app = flask.Flask(__name__)
app.testing = True

0 comments on commit ce70131

Please sign in to comment.