Лучший способ подавления исключений, возникающих при недоступности стороннего сервиса? - PullRequest
3 голосов
/ 11 сентября 2010

Я написал приложение Django, которое взаимодействует со сторонним API (Disqus, хотя эта деталь не важна) через оболочку Python.Когда служба недоступна, оболочка Python вызывает исключение.

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

try:
    somemodule.method_that_may_raise_exception(args)
except somemodule.APIError:
    pass

Некоторые представления содержат несколько таких вызовов.Является ли упаковка каждого вызова в try / кроме лучшим способом подавления возможных исключений?

Ответы [ 2 ]

2 голосов
/ 11 сентября 2010

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

т.е.когда я создаю приложения для Facebook, я создаю publish.py файл для хранения всех вызовов «опубликовать в прямом эфире».Функции в этом модуле именуются в зависимости от того, когда они должны быть вызваны.Т.е.:

# publish.py
def authorise_application(user):
    # API call "User joined app."

def post_anwser(anwser):
    # API call "User posted anwser to quiz".

Тогда ваши представления очень чисты:

# views.py
def post_anwser(request):
    ...
    if form.is_valid():
        form.save()
        publish.post_anwser(form.instance)

Когда ваш код организован таким образом, вы можете создать декоратор для игнорирования исключений:

# publish.py
def ignore_api_error(fun):
    def res(*args, **kwargs):
        try:
            return fun(*args, **kwargs):
        except someservice.ApiError:
            return None
    return res

@ignore_api_error
def authorised_application(user):
    # API call "User joined app."

@ignore_api_error
def posted_anwser(user, anwser):
    # API call "User posted anwser to quiz".

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

# publish.py
def some_function(user, message):
    pass

# views.py
def my_view():
    ...
    publish.ignore_api_error(publish.some_function)(user, message)
    ...
1 голос
/ 11 сентября 2010

Некоторые представления содержат несколько таких вызовов. Является ли упаковка каждого вызова в try / кроме лучшим способом подавления возможных исключений?

Вы можете обернуть вызов API внутри другой функции. Скажи:

def make_api_call(*args, **kwargs):
    try:
        return somemodule.method_that_may_raise_exception(*args, **kwargs)
    except somemodule.APIError:
        log.warn("....")           

Эта функция может вызываться вместо блока try/except в каждом представлении. Это, по крайней мере, поможет сократить количество строк кода, которые вы пишете, и предоставит общее место для обработки таких исключений.

Обновление

@ Йориру прав. Изменение кода для добавления этой хорошей практики.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...