forked from orbit-oss/flask
Better error message when view return type is not supported
Before, returning a `bool` from a route caused the error
```
[2019-05-31 10:08:42,216] ERROR in app: Exception on / [GET]
Traceback (most recent call last):
File "/Users/johnzeringue/Documents/ts-open/flask/flask/app.py", line 2070, in make_response
rv = self.response_class.force_type(rv, request.environ)
File "/Users/johnzeringue/Documents/ts-open/flask/env/lib/python3.7/site-packages/werkzeug/wrappers/base_response.py", line 269, in force_type
response = BaseResponse(*_run_wsgi_app(response, environ))
File "/Users/johnzeringue/Documents/ts-open/flask/env/lib/python3.7/site-packages/werkzeug/wrappers/base_response.py", line 26, in _run_wsgi_app
return _run_wsgi_app(*args)
File "/Users/johnzeringue/Documents/ts-open/flask/env/lib/python3.7/site-packages/werkzeug/test.py", line 1119, in run_wsgi_app
app_rv = app(environ, start_response)
TypeError: 'bool' object is not callable
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/Users/johnzeringue/Documents/ts-open/flask/flask/app.py", line 2393, in wsgi_app
response = self.full_dispatch_request()
File "/Users/johnzeringue/Documents/ts-open/flask/flask/app.py", line 1906, in full_dispatch_request
return self.finalize_request(rv)
File "/Users/johnzeringue/Documents/ts-open/flask/flask/app.py", line 1921, in finalize_request
response = self.make_response(rv)
File "/Users/johnzeringue/Documents/ts-open/flask/flask/app.py", line 2078, in make_response
reraise(TypeError, new_error, sys.exc_info()[2])
File "/Users/johnzeringue/Documents/ts-open/flask/flask/_compat.py", line 39, in reraise
raise value.with_traceback(tb)
File "/Users/johnzeringue/Documents/ts-open/flask/flask/app.py", line 2070, in make_response
rv = self.response_class.force_type(rv, request.environ)
File "/Users/johnzeringue/Documents/ts-open/flask/env/lib/python3.7/site-packages/werkzeug/wrappers/base_response.py", line 269, in force_type
response = BaseResponse(*_run_wsgi_app(response, environ))
File "/Users/johnzeringue/Documents/ts-open/flask/env/lib/python3.7/site-packages/werkzeug/wrappers/base_response.py", line 26, in _run_wsgi_app
return _run_wsgi_app(*args)
File "/Users/johnzeringue/Documents/ts-open/flask/env/lib/python3.7/site-packages/werkzeug/test.py", line 1119, in run_wsgi_app
app_rv = app(environ, start_response)
TypeError: 'bool' object is not callable
The view function did not return a valid response. The return type must be a string, tuple, Response instance, or WSGI callable, but it was a bool.
```
Now, it returns the more readable
```
[2019-05-31 10:36:19,500] ERROR in app: Exception on / [GET]
Traceback (most recent call last):
File "/Users/johnzeringue/Documents/ts-open/flask/flask/app.py", line 2400, in wsgi_app
response = self.full_dispatch_request()
File "/Users/johnzeringue/Documents/ts-open/flask/flask/app.py", line 1907, in full_dispatch_request
return self.finalize_request(rv)
File "/Users/johnzeringue/Documents/ts-open/flask/flask/app.py", line 1922, in finalize_request
response = self.make_response(rv)
File "/Users/johnzeringue/Documents/ts-open/flask/flask/app.py", line 2085, in make_response
" {rv.__class__.__name__}.".format(rv=rv))
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 bool.
```
Fixes #3214
This commit is contained in:
parent
6ac4b93779
commit
8bb7185284
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:``),
|
||||
all preserved request contexts are popped when the block exits,
|
||||
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
|
||||
.. _#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,
|
||||
)
|
||||
from werkzeug.routing import BuildError, Map, RequestRedirect, RoutingException, Rule
|
||||
from werkzeug.wrappers import BaseResponse
|
||||
|
||||
from . import cli, json
|
||||
from ._compat import integer_types, reraise, string_types, text_type
|
||||
|
|
@ -2063,7 +2064,7 @@ class Flask(_PackageBoundObject):
|
|||
status = headers = None
|
||||
elif isinstance(rv, dict):
|
||||
rv = jsonify(rv)
|
||||
else:
|
||||
elif isinstance(rv, BaseResponse) or callable(rv):
|
||||
# evaluate a WSGI callable, or coerce a different response
|
||||
# class to the correct type
|
||||
try:
|
||||
|
|
@ -2071,11 +2072,18 @@ class Flask(_PackageBoundObject):
|
|||
except TypeError as e:
|
||||
new_error = TypeError(
|
||||
"{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"
|
||||
" {rv.__class__.__name__}.".format(e=e, rv=rv)
|
||||
)
|
||||
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
|
||||
if status is not None:
|
||||
|
|
|
|||
|
|
@ -1218,17 +1218,21 @@ def test_response_type_errors():
|
|||
|
||||
with pytest.raises(TypeError) as e:
|
||||
c.get("/none")
|
||||
assert "returned None" in str(e)
|
||||
|
||||
assert "returned None" in str(e)
|
||||
|
||||
with pytest.raises(TypeError) as e:
|
||||
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")
|
||||
|
||||
with pytest.raises(TypeError) as e:
|
||||
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")
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue