gpt4 book ai didi

python - Twisted Python - 在 deferred 的回调函数调用中,引发的异常未显示在标准输出中

转载 作者:太空宇宙 更新时间:2023-11-04 05:54:10 24 4
gpt4 key购买 nike

测试设置

我有一个用于处理 POST 的异步 Twisted HTTP 服务器:

class HttpResource(Resource):
isLeaf = True;
def render_POST(self, request):
...

if __name__ == "__main__":
factory = Site(HttpResource())
reactor.listenTCP(8000, factory)
reactor.run()

我创建了一个引发异常的简单 test() 函数:

def test():
print "test() called"
raise Exception("Exception raised!")

在程序输出中捕获异常消息(即“引发异常!”)

如果我在 render_POST() 中调用 test(),则会引发异常并且输出会按预期显示消息:

Traceback (most recent call last):
raise Exception("Exception!")
exceptions.Exception: Exception!

但是,如果在 render_POST() 中我创建了一个指向执行 test() 的回调的延迟指向,则可能仍会引发异常(客户端收到 500 内部服务器错误)但没有异常错误消息(“引发异常! "短语) 显示。

问题

当回调中的函数调用引起异常错误消息时,我如何才能显示这些消息?

更新 1:提供了演示代码(需要 Twisted for server.py)
**更新 2:演示代码返回“NOT_DONE_YET”

客户端.py

import json, urllib2

if __name__ == "__main__":
while True:
cmd = raw_input("Enter cmd number (1, 2, or 0): ")
if cmd == str(1):
raw_data = {'cmd' : 'cmd1'}
elif cmd == str(2):
raw_data = {'cmd' : 'cmd2'}
elif cmd == str(0):
break;
req = urllib2.Request('http://localhost:8000')
req.add_header('Content-Type', 'application/json')
response = urllib2.urlopen(req, json.dumps(raw_data))
print response.read()

服务器.py

import json, time
from twisted.internet import reactor
from twisted.web.client import getPage
from twisted.web.resource import Resource
from twisted.web.server import Site, NOT_DONE_YET

def test():
print "test() called"
time.sleep(1)
raise Exception("Exception raised!")

def callback(result):
print "callback() called"
test()

class HttpResource(Resource):
isLeaf = True;
def render_POST(self, request):
msg = json.loads(request.content.getvalue())
if msg['cmd'] == 'cmd1': # call test() directly
test()
elif msg['cmd'] == 'cmd2': # call test() from callback
d = getPage('http://www.yahoo.com')
d.addCallbacks(callback, callback)

return NOT_DONE_YET

if __name__ == "__main__":
factory = Site(HttpResource())
reactor.listenTCP(8000, factory)
reactor.run()

最佳答案

这里有两个问题与您缺少的回溯相关。

您的程序的第一个问题是,当您从 render_POST 返回 None 时,这会告诉 twisted.web 您已完成对请求的处理并且应该建立连接立即关闭。当您的回调开始将一些数据推送到 HTTP channel 时,响应已经发送并且数据被丢弃。

第二个问题是您实际上根本没有将数据推送到连接。当 render_POST 本身引发异常时,调用它的代码可以捕获该异常。但是,调用 render_POST 的代码不期望返回 Deferred,即使它返回,您也不会在此处返回。

还有第三个问题,即您使用的是卡住整个程序的 time.sleep 而不是返回 Deferred 的 deferLater 稍后触发并允许并发任务继续进行。由于 time.sleep 完全不是重点,而且无论是否包含它,行为都是相同的,我们可以忽略它:-)。

有一种方法可以在 Twisted 内部解决这个问题,但更简单的方法是使用 Klein。 ,它会自动为您处理 Deferred

使用 Klein,您的示例将是:

import json

from klein import run, route
from twisted.web.client import getPage

def test():
print "test() called"
raise Exception("Exception raised!")

def callback(result):
print "callback() called"
test()

@route("/", methods=["POST"])
def example(request):
msg = json.loads(request.content.getvalue())
if msg['cmd'] == 'cmd1': # call test() directly
test()
elif msg['cmd'] == 'cmd2': # call test() from callback
d = getPage('http://www.yahoo.com')
return d.addCallbacks(callback, callback)

run("localhost", 8000)

注意return d.addCallbacks;如果您不返回结果,它将或多或少以与现在相同的方式继续失败。

关于python - Twisted Python - 在 deferred 的回调函数调用中,引发的异常未显示在标准输出中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28662213/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com