Следующий забавный случай взаимодействия частей Twisted Framework заставил меня потерять час времени, спешу рассказать, в надежде,
что это спасет чьё-то время. Итак, в Twisted есть модуль логгинга, twisted.python.log, в котором есть удобный метод log.err(), который позволяет записать в лог информацию о текущем исключении. А trial – это framework для написания юнит-тестов из того же Twisted. Их сочетание иногда приводит к проблеме
Итак, у меня был блок кода, похожий на пример ниже:
1 2 3 4 5 6 7 8 9 10 | from twisted.python import log def catcher(f): try: return f() except GoodException: return 'ERROR' except: log.err() raise UnknownException |
По смыслу он должен был логировать все неожиданные исключения и заменять их на более разумные. Я написал юнит-тест на такую функцию примерно следующего вида:
1 2 3 4 | def testCatcher(): def raiseBadException(): assert False self.assertEquals('ERROR', catcher, raiseBadException) |
При запуске юнит-тест говорил, что он завершился с ошибкой, т.к. было выброшено исключение
exceptions.AssertionError, т.е. то исключение, которое генерирует строка 3 в тесте. Но ведь оно было поймано catcher? Я долго бился с этой ситуацией (на самом деле код был сложнее, но суть его от этого не менялась), пока не понял, что если из-под trial (запускальщика юнит-тестов) сделать twisted.python.log.err, то вместо того, чтобы вывести в лог исключение, он помечает тест как ошибочный, при этом в качестве причины ошибки выводит текущее исключение! То есть тест отрабатывал штатно, но log.err() мой помечал его как ошибочный.
Вот такое вот не совсем очевидное взаимодействие…