• en
  • Language: ru
  • Documentation version: 1.1.x

Пользовательские страницы ошибок

Flask поставляется с удобной функцией abort(), которая прерывает запрос с кодом ошибки HTTP раньше времени. Она также предоставит вам обычную черно-белую страницу ошибки с базовым описанием, но без особых изысков.

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

Общие коды ошибок

Ниже приведены коды ошибок, которые часто отображаются пользователю, даже если приложение ведет себя правильно:

404 Not Found

Старое доброе сообщение «парень, ты ошибся при вводе URL». Это настолько распространенное явление, что даже новички в Интернете знают, что 404 означает: черт, того, что я искал, здесь нет. Очень хорошая идея - убедиться, что на странице 404 действительно есть что-то полезное, хотя бы ссылка на индекс.

403 Запрещено

Если на вашем сайте есть какой-либо контроль доступа, вам придется отправлять код 403 для запрещенных ресурсов. Поэтому убедитесь, что пользователь не потеряется при попытке получить доступ к запрещенному ресурсу.

410 Ушел

Знаете ли вы, что у «404 Not Found» есть брат по имени «410 Gone»? Немногие люди действительно реализуют это, но идея заключается в том, что ресурсы, которые ранее существовали и были удалены, отвечают символом 410 вместо 404. Если вы не удаляете документы навсегда из базы данных, а просто помечаете их как удаленные, окажите пользователю услугу и используйте вместо этого код 410 и выведите сообщение о том, что то, что он искал, было удалено навечно.

500 Внутренняя ошибка сервера

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

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

Обработчик ошибок - это функция, которая возвращает ответ при возникновении ошибки определенного типа, подобно тому, как представление - это функция, которая возвращает ответ при совпадении URL запроса. Ей передается экземпляр обрабатываемой ошибки, который, скорее всего, представляет собой HTTPException. Обработчику ошибки «500 Internal Server Error» будут передаваться не пойманные исключения в дополнение к явным 500 ошибкам.

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

Код состояния ответа не будет установлен на код обработчика. При возврате ответа от обработчика обязательно указывайте соответствующий код состояния HTTP.

Обработчик для «500 Internal Server Error» не будет использоваться при запуске в режиме отладки. Вместо этого будет показан интерактивный отладчик.

Вот пример реализации для исключения «404 Page Not Found»:

from flask import render_template

@app.errorhandler(404)
def page_not_found(e):
    # note that we set the 404 status explicitly
    return render_template('404.html'), 404

При использовании application factory pattern:

from flask import Flask, render_template

def page_not_found(e):
  return render_template('404.html'), 404

def create_app(config_filename):
    app = Flask(__name__)
    app.register_error_handler(404, page_not_found)
    return app

Пример шаблона может быть следующим:

{% extends "layout.html" %}
{% block title %}Page Not Found{% endblock %}
{% block body %}
  <h1>Page Not Found</h1>
  <p>What you were looking for is just not there.
  <p><a href="{{ url_for('index') }}">go somewhere nice</a>
{% endblock %}

Возврат ошибок API в формате JSON

При использовании Flask для веб-интерфейсов API можно использовать те же приемы, что и выше, для возврата JSON-ответов на ошибки API. Вызывается abort() с параметром description. errorhandler() будет использовать его в качестве сообщения об ошибке в формате JSON и установит код состояния 404.

from flask import abort, jsonify

@app.errorhandler(404)
def resource_not_found(e):
    return jsonify(error=str(e)), 404

@app.route("/cheese")
def get_one_cheese():
    resource = get_resource()

    if resource is None:
        abort(404, description="Resource not found")

    return jsonify(resource)