Исключение регистрации Python - PullRequest
22 голосов
/ 10 августа 2011

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

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

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

Ответы [ 2 ]

26 голосов
/ 10 августа 2011

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

    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 находится в составных выражениях .

6 голосов
/ 10 августа 2011

Этот метод корректен, хотя вместо 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
...