这是我使用Tornado的Facebook Messenger平台的代码。
class IndexHandler(tornado.web.RequestHandler):
@tornado.gen.coroutine
def get(self):
try:
mode = self.get_argument("hub.mode")
token = self.get_argument("hub.verify_token")
challenge = self.get_argument("hub.challenge")
except tornado.web.MissingArgumentError:
self.set_status(400)
self.write("Bad request")
self.finish()
if mode == "subscribe" and token == "secretgarden":
self.set_status(200)
self.write(challenge)
self.finish()
else:
self.set_status(403)
self.write("GTFO")
self.finish()
问题是当我运行它时(缺少hub.mode
arg),它会捕获MissingArgumentError
并抛出:
File "index.py", line 20, in get
if mode == "subscribe" and token == "secretgarden":
UnboundLocalError: local variable 'mode' referenced before assignment
我希望当它抓住我的MissingArgumentError
例外时,它会返回400
并结束我的请求。但它仍在运行下一个代码。我做错了吗?
P.s:我尝试在return
之后添加self.finish()
,它有效,但我没见过有人这样做过。文件说:
RequestHandler.finish(chunk = None)完成此响应,结束 HTTP请求。
我也读到了这个问题:Tornado: Can I run code after calling self.finish() in an asynchronous RequestHandler?
我的代码有问题。
答案 0 :(得分:2)
调用finish
不会从您的方法返回。您必须添加return
语句,否则将执行方法中的下一个语句。
实际上,您根本不需要致电finish
:Tornado请求处理程序会在finish
之类的协程完成后自动调用get
。
因此,要解决您的问题,请使用self.finish()
语句替换return
次来电。
答案 1 :(得分:0)
在端点方法结束时返回是一个很好的解决方案,但是如果您需要完成(例如通过重定向)其他方法,例如prepare
,initialize
和{,它将无法工作{1}},因为它们不一定是调用堆栈中的最后一个。 "官方"方法是引发tornado.web.Finish
异常,它会冒出来并从代码中的任何地方中断执行。我一直在广泛使用这样的东西:
get_current_user