Как сделать так, чтобы страницы ошибок во Flask не вызывали цикл ошибок из запрошенного проекта? - PullRequest
1 голос
/ 19 сентября 2019

У меня проблема с тем, что моя процедура обработки ошибок Flask отображает шаблоны в контексте схемы, в которой произошла ошибка.Мне нужен совет для улучшения архитектуры или как правильно устранить проблему.

Упрощенный макет моего приложения фляги выглядит следующим образом:

app/
    errors/
        templates/
            errors/
                500.html
    handlers.py

    sales/
        templates/
        __init__.py

В salse/__init__.py есть @bp.contex_processor для инъекции объекта cart, чтобы сделать его доступным во всех sales/templates/ (как обычно current_user):

salse/__init__.py

@bp.context_processor
def inject_cart():
    return dict(cart = cli.request('https://1.1.1.1/cart/load))
handler.py

@bp.app_errorhandler(500)
def internal_error(error):
    return render_template('500.html'), 500

Корзина загружена из внешней системы.

Проблема связана с обработкой ошибок соединения с внешней системой.

Требуемый сценарий

  1. Пользователь долгое время не работал - внешняя система закрыла соединение.
  2. Пользователь что-то щелкает
  3. В пакете подключения к внешней системе существует исключение «Авторизация для пользователя истекла»
  4. Flask отлавливает ошибку и отображает errors/500.html, который запрашиваетпользователь должен снова войти в систему (а также выполнить авторизацию для сторонней системы в фоновом режиме).

Текущий сценарий

  1. , как указано выше
  2. , каквыше
  3. как выше
  4. Flask ловит ошибку и вызывает render_template(errors/500.html)
  5. Внутри render_template('errors/500.html') flask.app.Flask#update_template_context() проверяет, что шаблон запроса (reqctx.request.blueprint) - это sales и, наконец, выполняет inject_cart()
  6. inject_cart(): пытается запросить стороннюю систему, но соединение закрывается, поэтому снова возникает ошибка из 3. ......
  7. Наконец, Flask показывает, что он встроен.на странице «Ошибка сервера».

Я думаю, что это нехорошо, что обработка ошибок не отделена от светокопии, где произошла ошибка, вызывающая флуд.

Но есть ли у васпредложение по лучшей структуре приложения, чтобы опустить эту проблему?Или, может быть, я не должен использовать render_template() для обработки шаблонов ошибок?

Пока я просто использовал redirect() вместо render_template().Но я чувствую, что есть лучшее решение.

1 Ответ

0 голосов
/ 19 сентября 2019

Предполагая, что ваше приложение Flask определено в app/__init__.py, я думаю, что ваша структура шаблонов должна быть

app/
    templates/
        errors/
            500.html
    handlers.py

    sales/
        templates/
        __init__.py

То есть, если вы не указали папку шаблона при инициализации app / blueprint.См. help(flask.Flask)

:param template_folder: the folder that contains the templates that should
                        be used by the application.  Defaults to
                        ``'templates'`` folder in the root path of the
                        application.```

РЕДАКТИРОВАТЬ: Чтобы добавить ясности

Вы можете переопределить шаблоны модулей в главном каталоге шаблонов вашего приложения.Вы не можете переопределить основные шаблоны вашего приложения в модуле (без использования некоторых базовых операций jinja).Поэтому, если ваша структура выглядит следующим образом:

app/
    templates/
        errors/
            500.html
    handlers.py

    sales/
        templates/
            errors/
                500.html
        __init__.py

План продаж app_errorhandler переопределит ваши приложения errorhandler, но при попытке визуализации errors/500.html будет отображаться app/templates/errors/500.html.Я считаю, что это сделано специально для того, чтобы разрешить переопределение шаблонов модулей сторонних производителей.

Лучшее соглашение - вкладывать шаблоны модулей в имя модуля, например такую ​​структуру:

app/
    templates/
        errors/
            500.html
    handlers.py

    sales/
        templates/
            sales/
                errors/
                    500.html
        __init__.py

Тогда ваш план продаж может обрабатывать свои собственные 500 ошибок, например

@bp.app_errorhandler(500)
def internal_error(error):
    return render_template('sales/errors/500.html'), 500

Тогда, если вы действительно этого хотите или можете, вы можете переопределить шаблоны ошибок модуля продаж

app/
    templates/
        sales/
            errors/
                500.html
        errors/
            500.html
    handlers.py

    sales/
        templates/
            sales/
                errors/
                    500.html
        __init__.py
...