Spec-Zone.ru › Flask 1.0

Ошибки приложений

Журнал изменений

Введено в версии 0.3.

Приложения выходят из строя, серверы выходят из строя. Рано или поздно в рабочей среде вы столкнетесь с исключением. Даже если ваш код на 100% правильный, время от времени будут появляться исключения. Почему? Потому что всё остальное, что вовлечено, может выйти из строя. Вот некоторые ситуации, в которых идеально работающий код может привести к ошибкам сервера:

  • клиент преждевременно прервал запрос, и приложение всё ещё считывало входящие данные
  • сервер базы данных был перегружен и не смог обработать запрос
  • полностью заполнена файловая система
  • жесткий диск упал
  • перегружен бэкенд-сервер
  • ошибка программирования в используемой библиотеке
  • соединение сервера с другой системой по сети прервалось

И это лишь небольшой пример проблем, с которыми вы можете столкнуться. Так как же справиться с подобными проблемами? По умолчанию, если ваше приложение работает в режиме рабочей среды, Flask отобразит для вас очень простую страницу и запишет исключение в logger.

Но вы можете сделать больше, и мы рассмотрим несколько лучших способов обработки ошибок.

Инструменты для ведения журнала ошибок

Отправка писем об ошибках, даже только для критических, может стать непосильной задачей, если достаточно пользователей сталкиваются с ошибками, и журналы ошибок обычно не просматриваются. Поэтому мы рекомендуем использовать Sentry для работы с ошибками приложения. Он доступен как открытый проект на GitHub и также доступен в виде хостированной версии, которую можно бесплатно попробовать. Sentry агрегирует дублирующие ошибки, сохраняет полный стек вызовов и локальные переменные для отладки и отправляет вам письма на основе новых ошибок или пороговых значений частоты.

Для использования Sentry вам необходимо установить клиент raven с дополнительными flask зависимостями:

$ pip install raven[flask]

Затем добавьте это в ваше приложение Flask:

from raven.contrib.flask import Sentry
sentry = Sentry(app, dsn='YOUR_DSN_HERE')

Или, если вы используете фабрики, вы также можете инициализировать его позже:

from raven.contrib.flask import Sentry
sentry = Sentry(dsn='YOUR_DSN_HERE')

def create_app():
    app = Flask(__name__)
    sentry.init_app(app)
    ...
    return app

Значение YOUR_DSN_HERE необходимо заменить значением DSN, полученным из вашей установки Sentry.

После этого сбои автоматически отправляются в Sentry, и вы можете получать уведомления об ошибках.

Обработчики ошибок

Вы, возможно, захотите показать пользователю пользовательские страницы ошибок, когда произойдёт ошибка. Это можно сделать, зарегистрировав обработчики ошибок.

Обработчик ошибок — это обычная функция представления, возвращающая ответ, но вместо регистрации по маршруту она регистрируется для исключения или кода HTTP-статуса, который был поднят при попытке обработки запроса.

Регистрация

Регистрируйте обработчики, декорируя функцию с помощью errorhandler(). Или используйте register_error_handler(), чтобы зарегистрировать функцию позже. Не забудьте установить код ошибки при возврате ответа.

@app.errorhandler(werkzeug.exceptions.BadRequest)
def handle_bad_request(e):
    return 'bad request!', 400

# or, without the decorator
app.register_error_handler(400, handle_bad_request)

werkzeug.exceptions.HTTPException подклассы, такие как BadRequest, и их HTTP-коды взаимозаменяемы при регистрации обработчиков. (BadRequest.code == 400)

Нестандартные HTTP-коды не могут быть зарегистрированы кодом, потому что они не известны Werkzeug. Вместо этого определите подкласс HTTPException с соответствующим кодом и зарегистрируйте и поднимите этот класс исключения.

class InsufficientStorage(werkzeug.exceptions.HTTPException):
    code = 507
    description = 'Not enough storage space.'

app.register_error_handler(InsuffcientStorage, handle_507)

raise InsufficientStorage()

Обработчики могут быть зарегистрированы для любого класса исключений, а не только для подклассов HTTPException или кодов HTTP-статуса. Обработчики могут быть зарегистрированы для конкретного класса или для всех подклассов родительского класса.

Обработка

Когда Flask перехватывает исключение во время обработки запроса, он сначала ищет его по коду. Если для кода не зарегистрирован обработчик, он ищет его по иерархии классов; выбирается наиболее специфичный обработчик. Если обработчик не зарегистрирован, подклассы HTTPException показывают общее сообщение об их коде, а другие исключения преобразуются в общую ошибку 500 Internal Server Error.

Например, если поднято исключение ConnectionRefusedError, и зарегистрирован обработчик для ConnectionError и ConnectionRefusedError, вызывается более специфический обработчик ConnectionRefusedError с экземпляром исключения для генерации ответа.

Обработчики, зарегистрированные в модуле, имеют приоритет над теми, что зарегистрированы глобально в приложении, если запрос обрабатывается модулем, который поднял исключение. Однако модуль не может обрабатывать ошибки маршрутизации 404, потому что ошибка 404 возникает на уровне маршрутизации до определения модуля.

Журнал изменений

Изменено в версии 0.11: Обработчики имеют приоритет по специфичности классов исключений, для которых они зарегистрированы, а не в порядке их регистрации.

Ведение журнала

См. Ведение журнала для получения информации о том, как записывать исключения, например, отправляя их по электронной почте администраторам.

© 2007–2020 Pallets
Licensed under the BSD 3-clause License.
https://flask.palletsprojects.com/en/1.0.x/errorhandling/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API