2016-11-18 10 views
4

Прочитав http://krondo.com/an-introduction-to-asynchronous-programming-and-twisted/, у меня есть базовое понимание Twisted. Я создал инфраструктуру тестирования, которую также используют несколько других людей. Время от времени мы сталкиваемся с ошибками типа Unhandled error in Deferred, если в коде есть ошибки или опечатки. Проблема в том, что с этими ошибками не всегда сопровождается трассировка стека, что затрудняет отладку людей.Отсутствие следов стека с «необработанной ошибкой в ​​отложенной» при использовании Python Twisted

Я воспроизвел эту проблему с помощью следующего простого кода:

from twisted.internet import defer, reactor 
from twisted.internet.task import deferLater 


def sleep(delay): 
    """Twisted safe sleep. 

    When using Twisted, it is not safe to call time.sleep(). So 
    we have this function to emulate the behavior. 

    """ 
    return deferLater(reactor, delay, lambda: None) 


@defer.inlineCallbacks 
def run_test(): 
    print 'run_test: start' 
    bug() 
    yield sleep(1) 
    print 'run_test: stop' 


@defer.inlineCallbacks 
def run_tests(): 

    def err(arg): 
     print 'err', arg 
     return arg 

    def success(arg): 
     print 'success', arg 
     return arg 

    d = run_test() 
    #d.addCallbacks(success, err) 

    try: 
     yield d 
    finally: 
     reactor.stop() 


reactor.callWhenRunning(run_tests) 
reactor.run() 

Когда я запускаю этот код, я вижу следующий вывод:

run_test: start 
Unhandled error in Deferred: 

И линии, если я раскомментировать addCallbacks() выше, затем я получаю информацию о трассировке стека:

run_test: start 
err [Failure instance: Traceback: <type 'exceptions.NameError'>: global name 'bug' is not defined 
/usr/local/lib/python2.7/dist-packages/twisted/internet/defer.py:1406:unwindGenerator 
/usr/local/lib/python2.7/dist-packages/twisted/internet/defer.py:1260:_inlineCallbacks 
tmp.py:34:run_tests 
/usr/local/lib/python2.7/dist-packages/twisted/internet/defer.py:1406:unwindGenerator 
--- <exception caught here> --- 
/usr/local/lib/python2.7/dist-packages/twisted/internet/defer.py:1260:_inlineCallbacks 
tmp.py:18:run_test 
] 
Unhandled error in Deferred: 

Вопрос в том, есть ли способ g et трассировка стека без необходимости добавлять обратные вызовы на всех сайтах отсрочки?

ответ

4

Класс Deferred имеет тонны try/except magic, до такой степени, что ошибки довольно хорошо отвлечены от конечного пользователя и только легко достигаются через addErrback. Если возникают ошибки, это признак того, что вы нарушили функциональность. В синхронных приложениях вы можете инкапсулировать «проблемный раздел» в блок try/except. В случае inlineCallbacks, тот же метод может быть использован:

try: 
    run_test() 
except Exception as err: 
    # handle error here 
finally: 
    reactor.stop() 

Поскольку ошибка происходит в функции run_test(), поймать исключение при выполнении этой функции, а затем обработать ошибку в соответствии с вашими требованиями.

Однако, если вы не планируете «обрабатывать» ошибки, а вы хотите, запись, которая произошла ошибка, то вы должны рассмотреть вопрос об использовании Twisted logger функциональность. Это поймает ваши необработанные трассировки и зарегистрирует их где-нибудь.

+0

Извините, что не писал ранее. Это действительно помогает. – Akhi

+0

Упоминающий регистратор значим для тех, кто просто привыкает к Twisted. – dval