Flask - Как создать собственный код прерывания ()?

Flask имеет хороший обработчик ошибок с использованием abort() или когда ошибка действительно произошла.

В документации Flask есть пример обработчика ошибки 404:

@app.errorhandler(404)
def not_found(error):
    return render_template('404.html'), 404

Итак, я попытался создать собственный код ошибки, например

if False:
    abort(777)

@app.errorhandler(777)
def something_is_wrong(error):
    return render_template('777.html'), 777

Но это не работает, и отладчик Werkzeug говорит: LookupError: нет исключений для 777.

Я нашел этот вопрос, в котором говорится Я должен сделать это так:

if False:
    return '777 error', 777

К сожалению, приведенный выше код выдает белый экран, даже отладчик Werkzeug не выходит

Я знаю, что могу просто сделать:

if False:
    return render_template('777.html')

Но это сделает код чище, если я буду использовать abort(). Есть ли способ создать собственный код ошибки?


person hrsetyono    schedule 05.09.2012    source источник
comment
Если вы используете Flask 1.0, кажется, что подход изменился, и вы можете вызывать и перехватывать пользовательские исключения: flask.pocoo.org/docs/1.0/patterns/apierrors   -  person Tom Saleeba    schedule 02.05.2019


Ответы (4)


Список возможных кодов состояния HTTP фиксируется Управлением по присвоению номеров в Интернете, поэтому вы не можете добавить собственный код. Werkzeug распознает это и пытается остановить отправку бессмысленного кода в браузер. Просмотрите список кодов состояния, чтобы найти тот, который соответствует вашей ошибке, и используйте его.

Изменить: Добавление кодов состояния в Werkzeug/Flask

import werkzeug.exceptions as ex
from flask import Flask, abort

class PaymentRequired(ex.HTTPException):
    code = 402
    description = '<p>You will pay for this!</p>'

abort.mappings[402] = PaymentRequired

app = Flask(__name__)

@app.route('/')
def mainpage():
    abort(402)

@app.errorhandler(402)
def payme(e):
    return 'Pay me!'

app.run()
person Abe Karplus    schedule 05.09.2012
comment
Спасибо, я использую ошибку 400 bad_request, когда пользователь вручную ввел неправильное значение в URL-адресе (поскольку URL-адрес содержит пользовательский ввод из раскрывающегося списка). Это работает, но правильно ли это? - person hrsetyono; 05.09.2012
comment
Вероятно, зависит от того, почему вы отказываетесь от ввода. Другим подходящим/распространенным кодом может быть 404 или даже 403, если вы блокируете из соображений безопасности. - person Thomas Orozco; 05.09.2012
comment
А 402? Этот не определен в werkzeug, но он должен быть допустимым. - person Pwnna; 26.02.2013
comment
@ultimatebuster Это не определено, потому что, как указано в списке, оно зарезервировано для использования в будущем. Я сомневаюсь, что Payment Required является точным описанием вашей ошибки, поэтому не советую 402. Просто сделайте return something_is_wrong() вместо abort(777). Это чисто и не противоречит стандарту. - person Abe Karplus; 26.02.2013
comment
Собственно, именно это я и хочу сказать. Хочу сказать: за данную услугу требуется оплата. - person Pwnna; 26.02.2013
comment
Ой, извини. Я просмотрю исходный код Werkzeug, чтобы узнать, как можно добавить новый код ошибки. - person Abe Karplus; 26.02.2013
comment
Мне нужно отправить обратно 504 (тайм-аут шлюза), но Flask, похоже, это тоже не поддерживает. Есть идеи, почему? - person Ben; 26.02.2013
comment
abort.mappings больше не существует; используйте вместо этого: exceptions.default_exceptions[402] = PaymentRequired - person claymation; 10.12.2014
comment
В моем случае (Flask==0.11.1, Werkzeug==0.11.10) abort.mapping[402] = PaymentRequired, а не сопоставления - person Stan Zeez; 12.07.2016
comment
во Flask 0.11.1 abort.mapping вместо abort.mappings, а abort.mapping менять не нужно, abort.mapping это default_exceptions, можно from werkzeug.exceptions import default_exceptions. - person xavierskip; 28.07.2016
comment
Ну, технически вы можете использовать собственный код, но ваш клиент может его не понять. API Twitter делает это, например, с кодом 420, который не является официальным кодом. - person bfontaine; 28.12.2016

В зависимости от прочтения вопроса это может пригодиться.

Существует более простой способ добавить обработку страницы ошибок клиента для определенного исключения, вы можете сделать это:

class MyCustom404(Exception):
    pass

@app.errorhandler(404)
def page_not_found(error):
    return render_template("errors/404.html"), 404

@app.errorhandler(MyCustom404)
def special_page_not_found(error):
    return render_template("errors/custom_404.html"), 404

... затем активируйте новый обработчик, когда вам это нужно, с помощью

raise MyCustom404

См. документацию здесь.

person Andrew Barrett    schedule 11.11.2013

В моем случае Flask==0.11.1 Werkzeug==0.11.10

Например, я использую код прерывания http 451.

если вы хотите использовать abort() с кодом, числом int, например, abort(451), сначала вы должны создать собственное HTTPException, подкласс HTTPException и добавить свое HTTPException к default_exceptions.

from werkzeug.exceptions import HTTPException, default_exceptions,  Aborter
class UnavailableForLegalReasons(HTTPException):
    code = 451
    description = 'BIG BROTHER IS WATCHING YOU'

default_exceptions[451] = UnavailableForLegalReasons
abort = Aborter()  # don't from flask import abort

@app.errorhandler(451)
def uflr(e):
    return e, 451

@app.route('/debug')
def debug():
    abort(451)

затем, когда вы получаете доступ к пути в браузере, вы можете посмотреть это введите здесь описание изображения

но фраза причины http НЕИЗВЕСТНА,

ты можешь изменить это

from werkzeug.http import HTTP_STATUS_CODES
HTTP_STATUS_CODES[451] = 'Unavailable For Legal Reasons'  # or even empty

введите описание изображения здесь

person xavierskip    schedule 29.07.2016

Вы также можете использовать Flask API и его систему обработки ошибок:

http://www.flaskapi.org/api-guide/exceptions/

person Mathieu Rodic    schedule 21.11.2014