Почему не вызывается обработчик для HTTPException, когда вызывается abort с экземпляром Response? - PullRequest
0 голосов
/ 29 марта 2020
from flask import Flask, abort, Response

from werkzeug.exceptions import HTTPException

app = Flask(__name__)


@app.errorhandler(HTTPException)
def http_exception_handler(e: HTTPException):
    msg = 'http_exception_handler is called.'
    print(msg)
    return msg


@app.route('/')
def index():
    try:
        abort(Response('I am the response passed to abort.', 400))
    except Exception as e:
        print(f'Raised error is an instance of HTTPException: {isinstance(e, HTTPException)}')
        raise e

    return 'Index successfully produced a response.'

В приведенном выше коде почему зарегистрированный обработчик для HTTPException не вызывается, когда функция abort вызывается с объектом Response? Выполнение кода указывает на то, что ошибка abort является экземпляром HTTPException.

1 Ответ

1 голос
/ 30 марта 2020

TL; DR: не передавать объект Response. Используйте HTTP-код, если вы хотите использовать ErrorHandler.

Итак, все сложнее, как кажется. Вы можете покопаться в коде Werkzeug и Flask, чтобы увидеть, что происходит. Я не буду подробно описывать шаги.

Итак, abort () вызывается для класса Aborter. Это создаст HTTPException из вашего объекта Response.

Если вы выполните следующую команду, у вас будет:

>>> print(HTTPException(response=Response("BODY",404)))
??? Unknown Error: None

У этого HTTPException нет кода.

>>> print(HTTPException(response=Response("BODY", 404)).code)
None

Это интерпретируется обработчиком ошибок.

def handle_http_exception(self, e):
    if e.code is None:
        return e # Here's your return

    # This is never called.
    handler = self._find_error_handler(e)
    if handler is None:
        return e
    return handler(e)

Тогда ваш декоратор обработчика никогда не будет вызван.

Так что это часть подробных шагов. Но так как Flask и Werkzeug хорошо закодированы. Вы можете непосредственно прочитать здесь о классе HTTPException:

def get_response(self, environ=None):
    """Get a response object.  If one was passed to the exception
    it's returned directly.

Это означает, что это означает, что оно возвращается напрямую. И это имеет смысл. Зачем вам go на обработчике ошибок , если вы уже справились с ошибкой.

Если вы хотите go глубже в коде, вот некоторые ссылки на github:

Werkzeug Exception Flask Класс приложения

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...