always pass InternalServerError instance to 500 handler

This commit is contained in:
David Lord 2019-06-19 13:58:55 -07:00
parent 2fa30f6a9e
commit 9054f6d639
No known key found for this signature in database
GPG key ID: 7A1C87E3F5BC42A8
3 changed files with 146 additions and 11 deletions

View file

@ -6,6 +6,7 @@ tests.test_user_error_handler
:copyright: © 2010 by the Pallets team.
:license: BSD, see LICENSE for more details.
"""
import pytest
from werkzeug.exceptions import Forbidden
from werkzeug.exceptions import HTTPException
from werkzeug.exceptions import InternalServerError
@ -25,7 +26,13 @@ def test_error_handler_no_match(app, client):
@app.errorhandler(500)
def handle_500(e):
return type(e).__name__
assert isinstance(e, InternalServerError)
original = getattr(e, "original_exception", None)
if original is not None:
return "wrapped " + type(original).__name__
return "direct"
@app.route("/custom")
def custom_test():
@ -35,9 +42,14 @@ def test_error_handler_no_match(app, client):
def key_error():
raise KeyError()
@app.route("/abort")
def do_abort():
flask.abort(500)
app.testing = False
assert client.get("/custom").data == b"custom"
assert client.get("/keyerror").data == b"KeyError"
assert client.get("/keyerror").data == b"wrapped KeyError"
assert client.get("/abort").data == b"direct"
def test_error_handler_subclass(app):
@ -194,3 +206,84 @@ def test_default_error_handler():
assert c.get("/forbidden").data == b"forbidden"
# Don't handle RequestRedirect raised when adding slash.
assert c.get("/slash", follow_redirects=True).data == b"slash"
class TestGenericHandlers(object):
"""Test how very generic handlers are dispatched to."""
class Custom(Exception):
pass
@pytest.fixture()
def app(self, app):
@app.route("/custom")
def do_custom():
raise self.Custom()
@app.route("/error")
def do_error():
raise KeyError()
@app.route("/abort")
def do_abort():
flask.abort(500)
@app.route("/raise")
def do_raise():
raise InternalServerError()
app.config["PROPAGATE_EXCEPTIONS"] = False
return app
def report_error(self, e):
original = getattr(e, "original_exception", None)
if original is not None:
return "wrapped " + type(original).__name__
return "direct " + type(e).__name__
@pytest.mark.parametrize("to_handle", (InternalServerError, 500))
def test_handle_class_or_code(self, app, client, to_handle):
"""``InternalServerError`` and ``500`` are aliases, they should
have the same behavior. Both should only receive
``InternalServerError``, which might wrap another error.
"""
@app.errorhandler(to_handle)
def handle_500(e):
assert isinstance(e, InternalServerError)
return self.report_error(e)
assert client.get("/custom").data == b"wrapped Custom"
assert client.get("/error").data == b"wrapped KeyError"
assert client.get("/abort").data == b"direct InternalServerError"
assert client.get("/raise").data == b"direct InternalServerError"
def test_handle_generic_http(self, app, client):
"""``HTTPException`` should only receive ``HTTPException``
subclasses. It will receive ``404`` routing exceptions.
"""
@app.errorhandler(HTTPException)
def handle_http(e):
assert isinstance(e, HTTPException)
return str(e.code)
assert client.get("/error").data == b"500"
assert client.get("/abort").data == b"500"
assert client.get("/not-found").data == b"404"
def test_handle_generic(self, app, client):
"""Generic ``Exception`` will handle all exceptions directly,
including ``HTTPExceptions``.
"""
@app.errorhandler(Exception)
def handle_exception(e):
return self.report_error(e)
assert client.get("/custom").data == b"direct Custom"
assert client.get("/error").data == b"direct KeyError"
assert client.get("/abort").data == b"direct InternalServerError"
assert client.get("/not-found").data == b"direct NotFound"