Added support for generic HTTPException handlers on app and blueprints

Error handlers are now returned in order of blueprint:code, app:code,
blueprint:HTTPException, app:HTTPException, None

Corresponding tests also added.

Ref issue #941, pr #1383, #2082, #2144
This commit is contained in:
cerickson 2017-05-22 15:57:31 -07:00
parent 668061a5fc
commit 4f815015b8
2 changed files with 69 additions and 44 deletions

View file

@ -1,5 +1,10 @@
# -*- coding: utf-8 -*-
from werkzeug.exceptions import Forbidden, InternalServerError, HTTPException, NotFound
from werkzeug.exceptions import (
Forbidden,
InternalServerError,
HTTPException,
NotFound
)
import flask
@ -32,29 +37,6 @@ def test_error_handler_no_match():
assert c.get('/keyerror').data == b'KeyError'
def test_default_error_handler():
app = flask.Flask(__name__)
@app.errorhandler(HTTPException)
def catchall_errorhandler(e):
assert isinstance(e, HTTPException)
assert isinstance(e, NotFound)
return 'default'
@app.errorhandler(Forbidden)
def catchall_errorhandler(e):
assert isinstance(e, Forbidden)
return 'forbidden'
@app.route('/forbidden')
def forbidden():
raise Forbidden()
c = app.test_client()
assert c.get('/undefined').data == b'default'
assert c.get('/forbidden').data == b'forbidden'
def test_error_handler_subclass():
app = flask.Flask(__name__)
@ -161,3 +143,53 @@ def test_error_handler_blueprint():
assert c.get('/error').data == b'app-error'
assert c.get('/bp/error').data == b'bp-error'
def test_default_error_handler():
bp = flask.Blueprint('bp', __name__)
@bp.errorhandler(HTTPException)
def bp_exception_handler(e):
assert isinstance(e, HTTPException)
assert isinstance(e, NotFound)
return 'bp-default'
@bp.errorhandler(Forbidden)
def bp_exception_handler(e):
assert isinstance(e, Forbidden)
return 'bp-forbidden'
@bp.route('/undefined')
def bp_registered_test():
raise NotFound()
@bp.route('/forbidden')
def bp_forbidden_test():
raise Forbidden()
app = flask.Flask(__name__)
@app.errorhandler(HTTPException)
def catchall_errorhandler(e):
assert isinstance(e, HTTPException)
assert isinstance(e, NotFound)
return 'default'
@app.errorhandler(Forbidden)
def catchall_errorhandler(e):
assert isinstance(e, Forbidden)
return 'forbidden'
@app.route('/forbidden')
def forbidden():
raise Forbidden()
app.register_blueprint(bp, url_prefix='/bp')
c = app.test_client()
assert c.get('/bp/undefined').data == b'bp-default'
assert c.get('/bp/forbidden').data == b'bp-forbidden'
assert c.get('/undefined').data == b'default'
assert c.get('/forbidden').data == b'forbidden'