Twisted 中的致命错误和延迟,停止延迟
我有一个问题,在 python 中使用正常的 try except 块,如果出现致命错误,您可以只返回,例如...
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.")
I have a problem, with normal try except blocks in python you can just return if there is a fatal error, 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
So how do this with deferreds, if I just return it goes onto execute the callbacks thinking the error is handled but how do I inform the user something went wrong and destroy the down river chain.
==== Update ===
mg thanks for the help but it didn't work, even with a fatal error the defer still returns to the callbacks afterwords
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.")
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
好的,一个全新的答案可以更好地解释 deferreds 工作。你应该认为,至少我是这样认为的,程序的流程是一个状态机。成功或失败就像机器的输入一样,可能会改变状态。在您的情况下,您有两种状态:已记录和未记录,以及三个输入:成功登录、身份验证错误以及因服务器问题而无法记录。只有其中一个输入是可恢复的,如果服务器因相同的奇怪问题而无法登录用户,在这种情况下,您可以通过重试登录来恢复问题。这里是新代码:
使用三个参数调用代码:最大重试次数,系统应重试登录用户,第三个参数是一个布尔值,指示用户凭据的正确性。尝试以下调用:
0 0 1
、3 2 0
、3 4 0
。我希望这个例子更能说明问题。
Ok, a whole new answer to explain better how deferreds work. You should think, at least I do, the flow of the program as a state machine. A success or a failure is like an input of that machine that, potentially, change the state. In your case you have two states, logged and non logged, and three inputs: successfully logged in, wrong authentication and could not logged for server problems. Only one of this inputs is recoverable, the case the server could not login the user for same strange problem and in this case you can recover the problem retrying the login. Here the new code:
Invoke the code with three parameters: the maximum number of retries, at which retry the system should login the user and the third is a boolean indicating the correctness of the user credentials. Try the following invocations:
0 0 1
,3 2 0
,3 4 0
.I hope this example is more explicative.