Merge pull request #3235 from johnzeringue/better-return-type-error
Better error message when view return type is not supported
This commit is contained in:
commit
52f9aa7ed6
3 changed files with 19 additions and 5 deletions
|
|
@ -64,6 +64,8 @@ Unreleased
|
||||||
- When using the test client as a context manager (``with client:``),
|
- When using the test client as a context manager (``with client:``),
|
||||||
all preserved request contexts are popped when the block exits,
|
all preserved request contexts are popped when the block exits,
|
||||||
ensuring nested contexts are cleaned up correctly. :pr:`3157`
|
ensuring nested contexts are cleaned up correctly. :pr:`3157`
|
||||||
|
- Show a better error message when the view return type is not
|
||||||
|
supported. :issue:`3214`
|
||||||
|
|
||||||
.. _#2935: https://github.com/pallets/flask/issues/2935
|
.. _#2935: https://github.com/pallets/flask/issues/2935
|
||||||
.. _#2957: https://github.com/pallets/flask/issues/2957
|
.. _#2957: https://github.com/pallets/flask/issues/2957
|
||||||
|
|
|
||||||
12
flask/app.py
12
flask/app.py
|
|
@ -27,6 +27,7 @@ from werkzeug.exceptions import (
|
||||||
default_exceptions,
|
default_exceptions,
|
||||||
)
|
)
|
||||||
from werkzeug.routing import BuildError, Map, RequestRedirect, RoutingException, Rule
|
from werkzeug.routing import BuildError, Map, RequestRedirect, RoutingException, Rule
|
||||||
|
from werkzeug.wrappers import BaseResponse
|
||||||
|
|
||||||
from . import cli, json
|
from . import cli, json
|
||||||
from ._compat import integer_types, reraise, string_types, text_type
|
from ._compat import integer_types, reraise, string_types, text_type
|
||||||
|
|
@ -2063,7 +2064,7 @@ class Flask(_PackageBoundObject):
|
||||||
status = headers = None
|
status = headers = None
|
||||||
elif isinstance(rv, dict):
|
elif isinstance(rv, dict):
|
||||||
rv = jsonify(rv)
|
rv = jsonify(rv)
|
||||||
else:
|
elif isinstance(rv, BaseResponse) or callable(rv):
|
||||||
# evaluate a WSGI callable, or coerce a different response
|
# evaluate a WSGI callable, or coerce a different response
|
||||||
# class to the correct type
|
# class to the correct type
|
||||||
try:
|
try:
|
||||||
|
|
@ -2071,11 +2072,18 @@ class Flask(_PackageBoundObject):
|
||||||
except TypeError as e:
|
except TypeError as e:
|
||||||
new_error = TypeError(
|
new_error = TypeError(
|
||||||
"{e}\nThe view function did not return a valid"
|
"{e}\nThe view function did not return a valid"
|
||||||
" response. The return type must be a string, tuple,"
|
" response. The return type must be a string, dict, tuple,"
|
||||||
" Response instance, or WSGI callable, but it was a"
|
" Response instance, or WSGI callable, but it was a"
|
||||||
" {rv.__class__.__name__}.".format(e=e, rv=rv)
|
" {rv.__class__.__name__}.".format(e=e, rv=rv)
|
||||||
)
|
)
|
||||||
reraise(TypeError, new_error, sys.exc_info()[2])
|
reraise(TypeError, new_error, sys.exc_info()[2])
|
||||||
|
else:
|
||||||
|
raise TypeError(
|
||||||
|
"The view function did not return a valid"
|
||||||
|
" response. The return type must be a string, dict, tuple,"
|
||||||
|
" Response instance, or WSGI callable, but it was a"
|
||||||
|
" {rv.__class__.__name__}.".format(rv=rv)
|
||||||
|
)
|
||||||
|
|
||||||
# prefer the status if it was provided
|
# prefer the status if it was provided
|
||||||
if status is not None:
|
if status is not None:
|
||||||
|
|
|
||||||
|
|
@ -1218,17 +1218,21 @@ def test_response_type_errors():
|
||||||
|
|
||||||
with pytest.raises(TypeError) as e:
|
with pytest.raises(TypeError) as e:
|
||||||
c.get("/none")
|
c.get("/none")
|
||||||
assert "returned None" in str(e)
|
|
||||||
|
assert "returned None" in str(e)
|
||||||
|
|
||||||
with pytest.raises(TypeError) as e:
|
with pytest.raises(TypeError) as e:
|
||||||
c.get("/small_tuple")
|
c.get("/small_tuple")
|
||||||
assert "tuple must have the form" in str(e)
|
|
||||||
|
assert "tuple must have the form" in str(e)
|
||||||
|
|
||||||
pytest.raises(TypeError, c.get, "/large_tuple")
|
pytest.raises(TypeError, c.get, "/large_tuple")
|
||||||
|
|
||||||
with pytest.raises(TypeError) as e:
|
with pytest.raises(TypeError) as e:
|
||||||
c.get("/bad_type")
|
c.get("/bad_type")
|
||||||
assert "it was a bool" in str(e)
|
|
||||||
|
assert "object is not callable" not in str(e)
|
||||||
|
assert "it was a bool" in str(e)
|
||||||
|
|
||||||
pytest.raises(TypeError, c.get, "/bad_wsgi")
|
pytest.raises(TypeError, c.get, "/bad_wsgi")
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue