Return a 400 status code on invalid JSON input

Instead of returning a 500 HTTP status code, return a 400 status code when the
received input is invalid JSON.
Also add a unit test for this case.

Closes-Bug: #1428462
Change-Id: Id02de0a7b8fcbcb07f7ac534519dcdc1cbb04839
This commit is contained in:
Stéphane Bisinger 2015-04-23 16:37:14 +02:00
parent 34f325a166
commit 8d9f82d7fe
2 changed files with 17 additions and 5 deletions

View File

@ -12,7 +12,7 @@ from simplegeneric import generic
from wsme.types import Unset from wsme.types import Unset
import wsme.types import wsme.types
import wsme.utils import wsme.utils
from wsme.exc import UnknownArgument, InvalidInput from wsme.exc import ClientSideError, UnknownArgument, InvalidInput
try: try:
@ -211,12 +211,15 @@ def datetime_fromjson(datatype, value):
def parse(s, datatypes, bodyarg, encoding='utf8'): def parse(s, datatypes, bodyarg, encoding='utf8'):
if hasattr(s, 'read'): jload = json.load
jdata = json.load(s) if not hasattr(s, 'read'):
else:
if six.PY3 and isinstance(s, six.binary_type): if six.PY3 and isinstance(s, six.binary_type):
s = s.decode(encoding) s = s.decode(encoding)
jdata = json.loads(s) jload = json.loads
try:
jdata = jload(s)
except ValueError:
raise ClientSideError("Request is not in valid JSON format")
if bodyarg: if bodyarg:
argname = list(datatypes.keys())[0] argname = list(datatypes.keys())[0]
kw = {argname: fromjson(datatypes[argname], jdata)} kw = {argname: fromjson(datatypes[argname], jdata)}

View File

@ -243,6 +243,15 @@ class TestRestJson(wsme.tests.protocol.RestOnlyProtocolTestCase):
print(r) print(r)
assert json.loads(r.text) == 2 assert json.loads(r.text) == 2
def test_invalid_json_body(self):
r = self.app.post('/argtypes/setint.json', '{"value": 2',
headers={"Content-Type": "application/json"},
expect_errors=True)
print(r)
assert r.status_int == 400
assert json.loads(r.text)['faultstring'] == \
"Request is not in valid JSON format"
def test_unknown_arg(self): def test_unknown_arg(self):
r = self.app.post('/returntypes/getint.json', '{"a": 2}', r = self.app.post('/returntypes/getint.json', '{"a": 2}',
headers={"Content-Type": "application/json"}, headers={"Content-Type": "application/json"},