From a5c4f36d59e172907d630cbb49f6a5c09b178ce8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stas=20SU=C8=98COV?= Date: Sat, 29 Aug 2015 00:55:31 +0300 Subject: [PATCH 1/2] Calling `flask.abort()` should not ignore `FlaskView.after_request`. --- flask_classy.py | 27 ++++++++++++++++----------- test_classy/test_view_wrappers.py | 5 +++++ test_classy/view_classes.py | 8 ++++++++ 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/flask_classy.py b/flask_classy.py index e0c5ccd..0b1bda2 100644 --- a/flask_classy.py +++ b/flask_classy.py @@ -14,6 +14,7 @@ import functools import inspect from werkzeug.routing import parse_rule +from werkzeug.exceptions import HTTPException from flask import request, Response, make_response import re @@ -197,17 +198,21 @@ def proxy(**forgettable_view_args): if response is not None: return response - response = view(**request.view_args) - if not isinstance(response, Response): - response = make_response(response) - - after_view_name = "after_" + name - if hasattr(i, after_view_name): - after_view = getattr(i, after_view_name) - response = after_view(response) - - if hasattr(i, "after_request"): - response = i.after_request(name, response) + try: + response = view(**request.view_args) + except HTTPException as response: + raise response + finally: + if not isinstance(response, Response): + response = make_response(response) + + after_view_name = "after_" + name + if hasattr(i, after_view_name): + after_view = getattr(i, after_view_name) + response = after_view(response) + + if hasattr(i, "after_request"): + response = i.after_request(name, response) return response diff --git a/test_classy/test_view_wrappers.py b/test_classy/test_view_wrappers.py index b05675c..f1f47eb 100644 --- a/test_classy/test_view_wrappers.py +++ b/test_classy/test_view_wrappers.py @@ -30,6 +30,11 @@ def test_after_request(): resp = client.get("/afterrequest/") eq_(b"After Request", resp.data) +def test_after_request_with_abort(): + resp = client.post("/afterrequest/") + ok_(b"Stopped by post" in resp.data) + ok_(AfterRequestView.after_called == True) + def test_decorated_view(): resp = client.get("/decorated/") eq_(b"Index", resp.data) diff --git a/test_classy/view_classes.py b/test_classy/view_classes.py index 5ad1e3a..3f0d5bd 100644 --- a/test_classy/view_classes.py +++ b/test_classy/view_classes.py @@ -1,3 +1,4 @@ +from flask import abort from flask_classy import FlaskView, route from functools import wraps @@ -143,12 +144,19 @@ def index(self): class AfterRequestView(FlaskView): + def before_request(self, name): + self.__class__.after_called = False + def after_request(self, name, response): + self.__class__.after_called = True return "After Request" def index(self): return "Index" + def post(self): + abort(422, "Stopped by post") + class VariedMethodsView(FlaskView): def index(self): From 3ac104b7c07030e44ff107c2c74289812676b7bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stas=20SU=C8=98COV?= Date: Mon, 31 Aug 2015 14:36:04 +0300 Subject: [PATCH 2/2] Make sure original 500 errors are propagated. --- flask_classy.py | 2 +- test_classy/test_view_wrappers.py | 5 +++++ test_classy/view_classes.py | 3 +++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/flask_classy.py b/flask_classy.py index 0b1bda2..51d56ba 100644 --- a/flask_classy.py +++ b/flask_classy.py @@ -203,7 +203,7 @@ def proxy(**forgettable_view_args): except HTTPException as response: raise response finally: - if not isinstance(response, Response): + if response and not isinstance(response, Response): response = make_response(response) after_view_name = "after_" + name diff --git a/test_classy/test_view_wrappers.py b/test_classy/test_view_wrappers.py index f1f47eb..d67d5a0 100644 --- a/test_classy/test_view_wrappers.py +++ b/test_classy/test_view_wrappers.py @@ -35,6 +35,11 @@ def test_after_request_with_abort(): ok_(b"Stopped by post" in resp.data) ok_(AfterRequestView.after_called == True) +def test_after_request_with_error(): + resp = client.put("/afterrequest/") + eq_(resp.status_code, 500) + ok_(AfterRequestView.after_called == True) + def test_decorated_view(): resp = client.get("/decorated/") eq_(b"Index", resp.data) diff --git a/test_classy/view_classes.py b/test_classy/view_classes.py index 3f0d5bd..ba80c6c 100644 --- a/test_classy/view_classes.py +++ b/test_classy/view_classes.py @@ -157,6 +157,9 @@ def index(self): def post(self): abort(422, "Stopped by post") + def put(self): + error('UnknownError') + class VariedMethodsView(FlaskView): def index(self):