Browse Source

Allow users to customize the behavior of flask.abort

Prior to werkzeug 0.12.2, it was possible to manipulate the status code
to exception type maps flask used by invoking::

    flask.abort.mapping.update(mapping)

This brings that back by creating a flask specific
werkzeug.exceptions.Aborter object and exposing it as flask.aborter. It
also implements a flask.abort function so that the correct docstring is
exposed::

    flask.aborter.mapping.update(mapping)
pull/2484/head
Michael Komitee 7 years ago
parent
commit
153254099b
  1. 3
      flask/__init__.py
  2. 25
      flask/helpers.py
  3. 27
      tests/test_helpers.py

3
flask/__init__.py

@ -14,7 +14,6 @@ __version__ = '0.13-dev'
# utilities we import from Werkzeug and Jinja2 that are unused # utilities we import from Werkzeug and Jinja2 that are unused
# in the module but are exported as public interface. # in the module but are exported as public interface.
from werkzeug.exceptions import abort
from werkzeug.utils import redirect from werkzeug.utils import redirect
from jinja2 import Markup, escape from jinja2 import Markup, escape
@ -22,7 +21,7 @@ from .app import Flask, Request, Response
from .config import Config from .config import Config
from .helpers import url_for, flash, send_file, send_from_directory, \ from .helpers import url_for, flash, send_file, send_from_directory, \
get_flashed_messages, get_template_attribute, make_response, safe_join, \ get_flashed_messages, get_template_attribute, make_response, safe_join, \
stream_with_context stream_with_context, aborter, abort
from .globals import current_app, g, request, session, _request_ctx_stack, \ from .globals import current_app, g, request, session, _request_ctx_stack, \
_app_ctx_stack _app_ctx_stack
from .ctx import has_request_context, has_app_context, \ from .ctx import has_request_context, has_app_context, \

25
flask/helpers.py

@ -20,6 +20,7 @@ from zlib import adler32
from threading import RLock from threading import RLock
import unicodedata import unicodedata
from werkzeug.routing import BuildError from werkzeug.routing import BuildError
from werkzeug.exceptions import Aborter
from functools import update_wrapper from functools import update_wrapper
try: try:
@ -1017,3 +1018,27 @@ def is_ip(value):
return True return True
return False return False
def abort(status, *args, **kwargs):
'''
Raises an :py:exc:`werkzeug.exceptions.HTTPException` for the given
status::
abort(404) # 404 Not Found
abort(Response('Hello World'))
If a status code is given it's looked up in the list of exceptions and will
raise that exception::
abort(404)
abort(Response('Hello World'))
To modify the status code to exception mapping, you can use
aborter.mapping.update::
aborter.mapping.update({404: MyCustom404Exception})
'''
return aborter(status, *args, **kwargs)
aborter = Aborter()

27
tests/test_helpers.py

@ -15,7 +15,7 @@ import uuid
import pytest import pytest
from werkzeug.datastructures import Range from werkzeug.datastructures import Range
from werkzeug.exceptions import BadRequest, NotFound from werkzeug.exceptions import BadRequest, NotFound, HTTPException
from werkzeug.http import http_date, parse_cache_control_header, \ from werkzeug.http import http_date, parse_cache_control_header, \
parse_options_header parse_options_header
@ -886,3 +886,28 @@ class TestHelpers(object):
assert rv.status_code == 200 assert rv.status_code == 200
assert rv.data == b'Hello' assert rv.data == b'Hello'
assert rv.mimetype == 'text/html' assert rv.mimetype == 'text/html'
class TestCustomAborterMapping(object):
def test_custom_aborter_mapping(self, app, client):
app.config['DEBUG'] = True
app.config['TRAP_BAD_REQUEST_ERRORS'] = False
class CustomNotFound(HTTPException):
code = 404
description = 'CUSTOM ABORTER MAPPINGS'
@app.route('/', methods=['GET'])
def index():
flask.abort(404)
try:
original = flask.aborter.mapping.get(404, '__UNSET__')
flask.aborter.mapping.update({404: CustomNotFound})
rv = client.get('/')
assert rv.status_code == 404
assert 'CUSTOM ABORTER MAPPINGS' in rv.data
finally:
if original != '__UNSET__':
flask.aborter.mapping.update({404: original})

Loading…
Cancel
Save