Как вернуть сообщения об ошибках в JSON с помощью Bottle HTTPError?

У меня есть сервер бутылок, который возвращает HTTPErrors как таковой:

return HTTPError(400, "Object already exists with that name")

Когда я получаю этот ответ в браузере, я хотел бы иметь возможность выбрать указанное сообщение об ошибке. Сейчас я вижу сообщение об ошибке в поле responseText ответа, но оно скрыто в строке HTML, которую я бы предпочел не анализировать, если в этом нет необходимости.

Есть ли способ, которым я могу специально установить сообщение об ошибке в Bottle, чтобы я мог выбрать его в JSON в браузере?


person Seventh Helix    schedule 15.06.2015    source источник
comment
Не имеет отношения, но... Это настоящая ошибка? Если это так, это не должен быть код состояния 400. ИМХО следует вернуть 409 Conflict,   -  person That1Guy    schedule 15.06.2015


Ответы (3)


HTTPError использует предопределенный HTML-шаблон для построения тела ответа. Вместо использования HTTPError вы можете использовать response с соответствующим кодом состояния и телом.

import json
from bottle import run, route, response

@route('/text')
def get_text():
    response.status = 400
    return 'Object already exists with that name'

@route('/json')
def get_json():
    response.status = 400
    response.content_type = 'application/json'
    return json.dumps({'error': 'Object already exists with that name'})

# Start bottle server.
run(host='0.0.0.0', port=8070, debug=True)
person dreyescat    schedule 15.06.2015

Я искал аналогичный способ обработки всех сообщений об ошибках в виде ответов JSON. Проблема с приведенным выше решением заключается в том, что они не делают это красивым и общим способом, т. Е. Обрабатывают любую возможную ошибку выталкивания, а не только определенный 400 и т. Д. Имхо, самое чистое решение - переопределить ошибку по умолчанию и затем работайте с пользовательским объектом бутылки:

class JSONErrorBottle(bottle.Bottle):
    def default_error_handler(self, res):
        bottle.response.content_type = 'application/json'
        return json.dumps(dict(error=res.body, status_code=res.status_code))

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

person Michael    schedule 02.10.2016
comment
было бы полезно, если бы вы описали, как использовать такой класс. Простое объявление класса само по себе, кажется, ничего не делает — как вы скажете Bottle использовать его в качестве обработчика ошибок по умолчанию? - person codebox; 30.12.2019

только начал работать с бутылкой, но порекомендовал бы что-то еще в духе:

import json
from bottle import route, response, error

@route('/text')
def get_text():
    abort(400, 'object already exists with that name')

# note you can add in whatever other error numbers
# you want, haven't found a catch-all yet
# may also be @application.error(400)
@error(400) #might be @application.error in some usages i think.
def json_error(error):
    """for some reason bottle don't deal with 
    dicts returned the same way it does in view methods.
    """
    error_data = {
        'error_message': error.body
    }
    response.content_type = 'application/json'
    return json.dumps(error_data)

не запускал выше, так что ожидайте ошибок, но вы поняли суть.

person ara.hayrabedian    schedule 17.11.2015