Подтвердить что ты не робот

Исключение журнала Python

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

import logging

log = logging.getLogger('module')

class MyAPIWrapper(library.APIClass):

    def __init__(self):
        self.log = logging.getLogger('module.myapiwrapper')


    def my_wrapper_method(self):
        try:
            response = self.call_api_method()
            return response.someData
        except APIException, e:
            self.log.exception('Oh noes!')
            raise e #Throw exception again so calling code knows it happened

Я немного сомневаюсь в том, что поймать и исключить, только чтобы зарегистрировать его, а затем повторно поднять его, чтобы вызывающий код мог что-то с этим сделать. Какая здесь правильная схема?

4b9b3361

Ответ 1

Нет ничего плохого в том, чтобы ловить лог. Однако я бы рекомендовал:

    try:
        response = self.call_api_method()
    except APIException, e:  # or 'as e' depending on your Python version
        self.log.exception('Oh noes!')
        raise #Throw exception again so calling code knows it happened
    else:
        return response.someData

Просто сделав голый raise, вы сохраните всю информацию о трассировке. Кроме того, более явным было бы ввести код, который будет происходить только в том случае, если в предложении else нет исключения, и он очистит, из какой строки вы извлекаете исключение.

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

Изменить: документация для try ... except ... else ... finally находится в составных операторах.

Ответ 2

Этот метод правильный, хотя вместо raise e вы должны просто использовать raise, который автоматически переподнимет последнее исключение. Это также один из редких случаев, когда использование одеяла except считается приемлемым.

Вот пример, очень похожий на то, что вы делаете из документов Python на Обработка исключений:

Последнее исключение может исключать имя (имена) исключения, чтобы служить в качестве подстановочного знака. Используйте это с особой осторожностью, так как легко маскировать реальную ошибку программирования таким образом! Он также может использоваться для печати сообщения об ошибке, а затем повторного восстания исключения (позволяющего вызывающему также обрабатывать исключение):

import sys

try:
    f = open('myfile.txt')
    s = f.readline()
    i = int(s.strip())
except IOError as (errno, strerror):
    print "I/O error({0}): {1}".format(errno, strerror)
except ValueError:
    print "Could not convert data to an integer."
except:
    print "Unexpected error:", sys.exc_info()[0]
    raise