Adds Blueprint Group exception decorator (#2238)
* Add exception decorator * Added tests * Fix line too long
This commit is contained in:
parent
a937e08ef0
commit
404c5f9f9e
@ -197,6 +197,27 @@ class BlueprintGroup(MutableSequence):
|
|||||||
"""
|
"""
|
||||||
self._blueprints.append(value)
|
self._blueprints.append(value)
|
||||||
|
|
||||||
|
def exception(self, *exceptions, **kwargs):
|
||||||
|
"""
|
||||||
|
A decorator that can be used to implement a global exception handler
|
||||||
|
for all the Blueprints that belong to this Blueprint Group.
|
||||||
|
|
||||||
|
In case of nested Blueprint Groups, the same handler is applied
|
||||||
|
across each of the Blueprints recursively.
|
||||||
|
|
||||||
|
:param args: List of Python exceptions to be caught by the handler
|
||||||
|
:param kwargs: Additional optional arguments to be passed to the
|
||||||
|
exception handler
|
||||||
|
:return a decorated method to handle global exceptions for any
|
||||||
|
blueprint registered under this group.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def register_exception_handler_for_blueprints(fn):
|
||||||
|
for blueprint in self.blueprints:
|
||||||
|
blueprint.exception(*exceptions, **kwargs)(fn)
|
||||||
|
|
||||||
|
return register_exception_handler_for_blueprints
|
||||||
|
|
||||||
def insert(self, index: int, item: Blueprint) -> None:
|
def insert(self, index: int, item: Blueprint) -> None:
|
||||||
"""
|
"""
|
||||||
The Abstract class `MutableSequence` leverages this insert method to
|
The Abstract class `MutableSequence` leverages this insert method to
|
||||||
|
@ -3,6 +3,7 @@ from pytest import raises
|
|||||||
from sanic.app import Sanic
|
from sanic.app import Sanic
|
||||||
from sanic.blueprint_group import BlueprintGroup
|
from sanic.blueprint_group import BlueprintGroup
|
||||||
from sanic.blueprints import Blueprint
|
from sanic.blueprints import Blueprint
|
||||||
|
from sanic.exceptions import Forbidden, InvalidUsage, SanicException, ServerError
|
||||||
from sanic.request import Request
|
from sanic.request import Request
|
||||||
from sanic.response import HTTPResponse, text
|
from sanic.response import HTTPResponse, text
|
||||||
|
|
||||||
@ -96,16 +97,28 @@ def test_bp_group(app: Sanic):
|
|||||||
def blueprint_1_default_route(request):
|
def blueprint_1_default_route(request):
|
||||||
return text("BP1_OK")
|
return text("BP1_OK")
|
||||||
|
|
||||||
|
@blueprint_1.route("/invalid")
|
||||||
|
def blueprint_1_error(request: Request):
|
||||||
|
raise InvalidUsage("Invalid")
|
||||||
|
|
||||||
@blueprint_2.route("/")
|
@blueprint_2.route("/")
|
||||||
def blueprint_2_default_route(request):
|
def blueprint_2_default_route(request):
|
||||||
return text("BP2_OK")
|
return text("BP2_OK")
|
||||||
|
|
||||||
|
@blueprint_2.route("/error")
|
||||||
|
def blueprint_2_error(request: Request):
|
||||||
|
raise ServerError("Error")
|
||||||
|
|
||||||
blueprint_group_1 = Blueprint.group(
|
blueprint_group_1 = Blueprint.group(
|
||||||
blueprint_1, blueprint_2, url_prefix="/bp"
|
blueprint_1, blueprint_2, url_prefix="/bp"
|
||||||
)
|
)
|
||||||
|
|
||||||
blueprint_3 = Blueprint("blueprint_3", url_prefix="/bp3")
|
blueprint_3 = Blueprint("blueprint_3", url_prefix="/bp3")
|
||||||
|
|
||||||
|
@blueprint_group_1.exception(InvalidUsage)
|
||||||
|
def handle_group_exception(request, exception):
|
||||||
|
return text("BP1_ERR_OK")
|
||||||
|
|
||||||
@blueprint_group_1.middleware("request")
|
@blueprint_group_1.middleware("request")
|
||||||
def blueprint_group_1_middleware(request):
|
def blueprint_group_1_middleware(request):
|
||||||
global MIDDLEWARE_INVOKE_COUNTER
|
global MIDDLEWARE_INVOKE_COUNTER
|
||||||
@ -130,10 +143,18 @@ def test_bp_group(app: Sanic):
|
|||||||
def blueprint_3_default_route(request):
|
def blueprint_3_default_route(request):
|
||||||
return text("BP3_OK")
|
return text("BP3_OK")
|
||||||
|
|
||||||
|
@blueprint_3.route("/forbidden")
|
||||||
|
def blueprint_3_forbidden(request: Request):
|
||||||
|
raise Forbidden("Forbidden")
|
||||||
|
|
||||||
blueprint_group_2 = Blueprint.group(
|
blueprint_group_2 = Blueprint.group(
|
||||||
blueprint_group_1, blueprint_3, url_prefix="/api"
|
blueprint_group_1, blueprint_3, url_prefix="/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@blueprint_group_2.exception(SanicException)
|
||||||
|
def handle_non_handled_exception(request, exception):
|
||||||
|
return text("BP2_ERR_OK")
|
||||||
|
|
||||||
@blueprint_group_2.middleware("response")
|
@blueprint_group_2.middleware("response")
|
||||||
def blueprint_group_2_middleware(request, response):
|
def blueprint_group_2_middleware(request, response):
|
||||||
global MIDDLEWARE_INVOKE_COUNTER
|
global MIDDLEWARE_INVOKE_COUNTER
|
||||||
@ -161,14 +182,23 @@ def test_bp_group(app: Sanic):
|
|||||||
_, response = app.test_client.get("/api/bp/bp1")
|
_, response = app.test_client.get("/api/bp/bp1")
|
||||||
assert response.text == "BP1_OK"
|
assert response.text == "BP1_OK"
|
||||||
|
|
||||||
|
_, response = app.test_client.get("/api/bp/bp1/invalid")
|
||||||
|
assert response.text == "BP1_ERR_OK"
|
||||||
|
|
||||||
_, response = app.test_client.get("/api/bp/bp2")
|
_, response = app.test_client.get("/api/bp/bp2")
|
||||||
assert response.text == "BP2_OK"
|
assert response.text == "BP2_OK"
|
||||||
|
|
||||||
|
_, response = app.test_client.get("/api/bp/bp2/error")
|
||||||
|
assert response.text == "BP2_ERR_OK"
|
||||||
|
|
||||||
_, response = app.test_client.get("/api/bp3")
|
_, response = app.test_client.get("/api/bp3")
|
||||||
assert response.text == "BP3_OK"
|
assert response.text == "BP3_OK"
|
||||||
|
|
||||||
assert MIDDLEWARE_INVOKE_COUNTER["response"] == 9
|
_, response = app.test_client.get("/api/bp3/forbidden")
|
||||||
assert MIDDLEWARE_INVOKE_COUNTER["request"] == 8
|
assert response.text == "BP2_ERR_OK"
|
||||||
|
|
||||||
|
assert MIDDLEWARE_INVOKE_COUNTER["response"] == 18
|
||||||
|
assert MIDDLEWARE_INVOKE_COUNTER["request"] == 16
|
||||||
|
|
||||||
|
|
||||||
def test_bp_group_list_operations(app: Sanic):
|
def test_bp_group_list_operations(app: Sanic):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user