Перевызов исключения как ошибки HTTP в Pyramid

У меня есть веб-приложение на python Pyramid, которое вызывает другой код на python, что может вызвать исключение. Вместо того, чтобы пользователь получал «Внутреннюю ошибку 500», я бы хотел, чтобы он получал более конкретную ошибку, например, если выдается MyException, отображается ошибка 503. Я пытался сделать это:

@view_config(context=MyException, permission='view')
def custom_exc(exc, request):
   raise HTTPServiceUnavailable(exc.message)

Однако это не удается, потому что по какой-то причине это неавторизовано:

HTTPForbidden: Unauthorized: custom_exc failed permission check

Мой ACL выглядит следующим образом:

class RootFactory(object):
    __acl__ = [
        (Allow, 'admin', ('view',))
        ]

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

Кто-нибудь знает, как решить эту проблему или как по-другому «сцепить» исключения в Pyramid?


person KimiNewt    schedule 26.01.2015    source источник
comment
Вы ознакомились с представлениями исключений? Я использовал их для захвата и возврата определенных ошибок, хотя при этом не сталкивался с ошибками авторизации.   -  person Peter Tirrell    schedule 29.01.2015


Ответы (1)


Узнайте из индивидуализированной версии известного примера приложения ToDoPyramid. Таким образом, я перевожу внутреннее техническое событие, исключение базы данных, в значимое сообщение для конкретного приложения в пользовательском коде представления исключения. Некоторые ребята называют это уровнем абстракции или сокрытием информации.

Не защищайте эти представления исключений с помощью разрешений, так как вы должны защищать код, который что-то делает и МОЖЕТ вызывать исключения.

from sqlalchemy.exc import OperationalError as SqlAlchemyOperationalError

@view_config(context=SqlAlchemyOperationalError)
def failed_sqlalchemy(exception, request):
    """catch missing database, logout and redirect to homepage, add flash message with error
    implementation inspired by pylons group message
    https://groups.google.com/d/msg/pylons-discuss/BUtbPrXizP4/0JhqB2MuoL4J
    """

    msg = 'There was an error connecting to database'
    request.session.flash(msg, queue='error')
    headers = forget(request)
    # Send the user back home, everything else is protected
    return HTTPFound(request.route_url('home'), headers=headers)
person Sascha Gottfried    schedule 29.01.2015