Исключение журнала 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
Я немного сомневаюсь в том, что поймать и исключить, только чтобы зарегистрировать его, а затем повторно поднять его, чтобы вызывающий код мог что-то с этим сделать. Какая здесь правильная схема?
Ответы
Ответ 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