Фатальные ошибки и отсрочки в Twisted, остановка отсроченного

1

У меня проблема, с обычной попыткой, кроме блоков в python, вы можете просто вернуться, если есть фатальная ошибка, ex...

try:
    logon()
except 404_Error:
    retry_logon(try = 2)

except AuthenticationProblem:
    error_label.SetText( "You password or username was wrong. Make sure that CAPS LOCK key is not on." )
    return#nothing more we can do here
else:
    #display user information or whatever

Итак, как это сделать с отсрочками, если я просто верну его, он выполнит обратные вызовы, думающие, что ошибка обрабатывается, но как я могу сообщить пользователю, что что-то пошло не так и разрушит цепочку рек вниз.

==== Обновление ===

mg спасибо за помощь, но это не сработало, даже с фатальной ошибкой отсрочка по-прежнему возвращается к обратным вызовам после слов

from twisted.internet import reactor
from twisted.internet.defer import Deferred as D

class NonFatalError(Exception):
    'non fatal error'
class FatalError(Exception):
    'fatal error'
def c(s):
    print "Callback called"
    print "Data Received: %s" % s
def e(f):
    print "Errorback Called"
    print "Error Type: %s" % type(f)
    print "Traceback"
    f.printTraceback()
    print "======================================="
    f.trap(NonFatalError)
    return "Error Handled"
def e_fatal(f, d):
    print "Errorback Called"
    print "Error Type: %s" % type(f)
    print "Traceback"
    f.printTraceback()
    print "======================================="
    print "Fatal Error"
    f.trap(FatalError)
    return "Fatal Error... Crash and die. No more callbacks should be called."

def trigger():
    d.errback(FatalError("This error is fatal to the defer"))

if __name__ == "__main__":
    d = D()
    d.addErrback(e)
    d.addErrback(e_fatal, d)
    d.addCallback(c)
    d.addCallback(c)
    d.addCallback(c)
    d.addCallback(c)
    reactor.callLater(3, trigger)
    reactor.callLater(10, reactor.stop)
    reactor.run()

    raw_input("Done.")
Теги:
error-handling
twisted

1 ответ

2
Лучший ответ

Хорошо, новый ответ, чтобы лучше объяснить, как отложить. Вы должны думать, по крайней мере, о том, что поток программы является конечным автоматом. Успех или неудача - это входной сигнал этой машины, который, возможно, изменит состояние. В вашем случае у вас есть два состояния: logged и non logged и три входа: успешно вошли в систему, неверная аутентификация и не удалось выполнить вход в систему для проблем с сервером. Только один из этих входов может быть восстановлен, если сервер не смог войти в систему для пользователя по той же странной проблеме, и в этом случае вы можете восстановить эту проблему, повторив логин. Здесь новый код:

import sys
from twisted.internet import reactor, defer


class FourOhFourError(Exception):
    pass


class AuthenticationError(Exception):
    pass


def logon(retry=3, success=2, wrong_auth=0):
    # do stuff
    d = defer.Deferred()
    # not_found is the only error recoverable
    d.addErrback(not_found, retry, success)
    if wrong_auth:
        reactor.callLater(0, d.errback, AuthenticationError("wrong auth"))
    else:
        if success == 0:
            reactor.callLater(0, d.callback, "Mario")
        else:
            reactor.callLater(0, d.errback, FourOhFourError("Not found"))
    return d


def not_found(failure, retry, success):
    failure.trap(FourOhFourError) # this is superfluous here
    print failure.getErrorMessage()
    if retry == 0:
        raise AuthenticationError("Max retries")
    # do stuff
    print "retring..."
    d = defer.Deferred()
    d.addCallback(logon, success-1)
    reactor.callLater(1, d.callback, retry-1) # not really clean here
    return d


def wrong_auth(failure):
    failure.trap(AuthenticationError) # this is superfluous here
    # do stuff
    print "something goes wrong"
    print failure.getErrorMessage()


def loggedIn(user):
    print "hello %s" % user


def stop(_):
    reactor.stop()


d = logon(*map(int, sys.argv[1:]))
d.addCallbacks(loggedIn, wrong_auth)
d.addBoth(stop)
reactor.run()

Вызвать код с тремя параметрами: максимальное количество попыток, при которых повторная попытка входа в систему должна войти в систему, а третья - логическая, указывающая правильность учетных данных пользователя. Попробуйте выполнить следующие вызовы: 0 0 1, 3 2 0, 3 4 0.

Я надеюсь, что этот пример более объяснительный.

  • 0
    Но что, если будет добавлено больше колбэков, тогда, когда error_auth вернет None, он не перейдет в цепочку колбэков со значением None
  • 0
    Вау, спасибо большое :-)
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню