This is my code for Facebook Messenger Platform using Tornado.
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()
The problem is when I run it (lack of hub.mode
arg), it will catch MissingArgumentError
and throw out:
File "index.py", line 20, in get
if mode == "subscribe" and token == "secretgarden":
UnboundLocalError: local variable 'mode' referenced before assignment
I expect when it catch my MissingArgumentError
exception, it will return 400
and end my request. But it still running next code. Did I do anything wrong?
P.s: I have tried add return
after self.finish()
, it worked, but I have not seen anyone do it. And the docs said:
RequestHandler.finish(chunk=None) Finishes this response, ending the HTTP request.
And I also read this question: Tornado: Can I run code after calling self.finish() in an asynchronous RequestHandler?
Something wrong with my code.
Calling finish
does not return from your method. You have to add a return
statement, otherwise the next statement in your method is executed.
Actually, you don't need to call finish
at all: Tornado request handlers automatically call finish
once a coroutine like get
completes.
So, to fix your problem, replace your self.finish()
calls with return
statements.