Reputation: 1507
I'm using the webapp2 framework in Google App Engine (Python). In webapp2 exception handling: exceptions in the WSGI app it's described how to handle 404 errors in a function:
import logging
import webapp2
def handle_404(request, response, exception):
logging.exception(exception)
response.write('Oops! I could swear this page was here!')
response.set_status(404)
def handle_500(request, response, exception):
logging.exception(exception)
response.write('A server error occurred!')
response.set_status(500)
app = webapp2.WSGIApplication([
webapp2.Route('/', handler='handlers.HomeHandler', name='home')
])
app.error_handlers[404] = handle_404
app.error_handlers[500] = handle_500
How can I handle the 404 error in a webapp2.RequestHandler
class, in the .get()
method of that class?
Edit:
The reason I want to call a RequestHandler
is to access the session (request.session
). Otherwise I'm not able to pass the current user to the template of the 404 error page. i.e. on the StackOverflow 404 error page you can see your username. I would like to display the username of the current user on my website's 404 error page as well. Is this possible in a function or does it has to be a RequestHandler
?
Correct code based on @proppy's answer:
class Webapp2HandlerAdapter(webapp2.BaseHandlerAdapter):
def __call__(self, request, response, exception):
request.route_args = {}
request.route_args['exception'] = exception
handler = self.handler(request, response)
return handler.get()
class Handle404(MyBaseHandler):
def get(self):
self.render(filename="404.html",
page_title="404",
exception=self.request.route_args['exception']
)
app = webapp2.WSGIApplication(urls, debug=True, config=config)
app.error_handlers[404] = Webapp2HandlerAdapter(Handle404)
Upvotes: 3
Views: 2192
Reputation: 10504
The calling convention of error handler and request handler callables are different:
error_handlers
takes (request, response, exception)
RequestHandler
takes (request, response)
You may use something similar to Webapp2HandlerAdapter
to adapt a webapp2.RequestHandler
to a callable.
class Webapp2HandlerAdapter(BaseHandlerAdapter):
"""An adapter to dispatch a ``webapp2.RequestHandler``.
The handler is constructed then ``dispatch()`` is called.
"""
def __call__(self, request, response):
handler = self.handler(request, response)
return handler.dispatch()
But you would have to sneak the extra exception argument in request route_args
.
Upvotes: 3