- en
- Language: ru
- Documentation version: 1.1.x
Реализация исключений API¶
Реализация RESTful API поверх Flask - очень распространенное явление. Одна из первых вещей, с которой сталкиваются разработчики, - это осознание того, что встроенные исключения недостаточно выразительны для API и что тип содержимого text/html, который они выдают, не очень полезен для потребителей API.
Лучшим решением, чем использование abort
для сигнализации об ошибках при неправильном использовании API, является реализация собственного типа исключения и установка обработчика ошибок для него, который выдает ошибки в том формате, который ожидает пользователь.
Простой класс исключений¶
Основная идея заключается в том, чтобы ввести новое исключение, которое может принимать соответствующее человекочитаемое сообщение, код статуса ошибки и некоторую необязательную полезную нагрузку, чтобы дать больше контекста для ошибки.
Вот простой пример:
from flask import jsonify
class InvalidUsage(Exception):
status_code = 400
def __init__(self, message, status_code=None, payload=None):
Exception.__init__(self)
self.message = message
if status_code is not None:
self.status_code = status_code
self.payload = payload
def to_dict(self):
rv = dict(self.payload or ())
rv['message'] = self.message
return rv
Теперь представление может поднять это исключение с сообщением об ошибке. Кроме того, дополнительная полезная нагрузка может быть предоставлена в виде словаря через параметр payload.
Регистрация обработчика ошибок¶
В этот момент представления могут поднять эту ошибку, но это немедленно приведет к внутренней ошибке сервера. Причина в том, что для этого класса ошибок не зарегистрирован обработчик. Однако его легко добавить:
@app.errorhandler(InvalidUsage)
def handle_invalid_usage(error):
response = jsonify(error.to_dict())
response.status_code = error.status_code
return response
Использование в представлениях¶
Вот как представление может использовать эту функциональность:
@app.route('/foo')
def get_foo():
raise InvalidUsage('This view is gone', status_code=410)