Reputation: 3125
I have two classes in my Tornado application.
First class is BaseRequestHandler
, which extends tornado.web.RequestHandler
and overrides prepare()
method of it for API Key validation of all incoming requests.
Second one is route specific class ChildRequestHandler
, which extends BaseRequestHandler
.
ChildRequestHandler
also has prepare()
method which does some parameter validation but before that it calls prepare()
method of BaseRequestHandler
.
Now, prepare()
method of both classes calls finish()
methods of tornado.web.RequestHandler
if validation fails.
Following are the examples of both the classes.
Base Class
class BaseRequestHandler(RequestHandler):
# Override Write Error method
def write_error(self, status_code, chunk):
self.set_status(status_code)
self.finish({'message': chunk})
# Prepare method to validate API Key
def prepare(self):
# Send Unauthorized error
if 'X-API-KEY' not in self.request.headers:
self.write_error(401, 'API Key {X-API-KEY} Required')
return None
# Set API Key from header
self.apikey = self.request.headers['X-API-KEY']
Child class
class ChildRequestHandler(BaseRequestHandler):
# Check for required parameters
def prepare(self):
# Call Prepare of base class
super(ChildRequestHandler, self).prepare()
username = self.get_query_argument('username', None)
if username is None:
self.write_error(400, 'Username {username} Required')
The problem occurs when validation fails in Base class. Then it throws Runtime error finish() called twice
as prepare()
method of child class is also executed regardless of validation result of Base class.
This can be solved by returning boolean from prepare()
method of Base class to identify whether the validation passed or not and then accordingly allow execution of prepare()
method of child class.
But is there anything like self.finished()
to identify whether the request is already finished? I checked the documentation and could not find any such method.
Upvotes: 0
Views: 685
Reputation: 22134
There's not a public finished()
method (although there's no reason why one couldn't be added). I recommend raising a subclass of tornado.web.HTTPError
instead of calling write_error
directly, so that prepare()
won't return normally after producing the error.
Upvotes: 2