Да, я не знал, что если вы вернете True
в __exit__()
, то исключение не будет возбуждено.
Теперь suppress_exception()
контекстный менеджер прост:
class suppress_exception(object):
def __init__(self, exceptions_to_catch, minutes=30):
self.exceptions_to_catch = exceptions_to_catch
self.timedelta = datetime.timedelta(minutes=minutes)
code = sys._getframe().f_back.f_code
self.cache_key = 'suppress_exception_' + code.co_filename + str(sys._getframe().f_back.f_lineno)
def __enter__(self):
return self
def __exit__(self, type, value, traceback):
datetime_of_first_failure = cache.get(self.cache_key)
now = datetime.datetime.now()
if not type:
cache.delete(self.cache_key)
if datetime_of_first_failure:
logging.info('Fine again. First failure was %s. Duration (first failure until ok): %s' % (
datetime_of_first_failure, now - datetime_of_first_failure))
return
if not issubclass(type, self.exceptions_to_catch):
# Thils will raise an exception
return
if not datetime_of_first_failure:
cache.set(self.cache_key, now)
datetime_of_first_failure = now
log_method = logging.warn
if datetime_of_first_failure + self.timedelta > now:
log_method = logging.info
log_method('%s %s (datetime_of_first_failure=%s)' % (type.__name__, value, datetime_of_first_failure))
return True