I am trying to raise a 401/403 status for when a user attempts to access something they don't have privileges to. I used the Webapp2 Exceptions example which generates the proper error codes for 404/500 "natural" events. Such as going to http://localhost:8080/nourl generates the proper 404 and messing up code generates a 500. But when I use the method such as below to set the code using self.error(XXX) I see the code in the console but it does not show up in the browser. EG If you leave self.error() empty it generates the proper 500 code. If you use self.error(500) the console outputs:
INFO 2012-05-09 18:25:29,549 dev_appserver.py:2891] "GET / HTTP/1.1" 500 -
But the browser is completely blank. Below is an example app that exhibits this behaviour. Simply change the self.error() line to the desired code and run. The expected result would be that it generates the proper response to the browser based on the code supplied, not just when a "natural" event occurs such as 404.
main.py
import webapp2
import wsgiref.handlers
import logging
from google.appengine.api import users
class HomeHandler(webapp2.RequestHandler):
def get(self):
user = users.get_current_user()
if user:
self.response.out.write("Hi :1", user.nickname)
else:
self.error(401)
app = webapp2.WSGIApplication([
(r'/', HomeHandler),
], debug=True)
def handle_401(request, response, exception):
logging.exception(exception)
response.write("401 Error")
response.set_status(401)
def handle_403(request, response, exception):
logging.exception(exception)
response.write("403 Error")
response.set_status(403)
def handle_404(request, response, exception):
logging.exception(exception)
response.write("404 Error")
response.set_status(404)
def handle_500(request, response, exception):
logging.exception(exception)
response.write("500 Error")
response.set_status(500)
app.error_handlers[401] = handle_401
app.error_handlers[403] = handle_403
app.error_handlers[404] = handle_404
app.error_handlers[500] = handle_500
# Run the application
def main():
app.run()
app.yaml
application: 401test
version: 1
runtime: python27
api_version: 1
threadsafe: yes
libraries:
- name: webapp2
version: latest
handlers:
- url: /.*
script: main.app
you are using py27 with threadsafe environment.
in app.yaml you set script: main.app
so the code after app is defined is not executed.
didn't test it but this should work:
# create a bare app
bare_app = webapp2.WSGIApplication(debug=True)
#define the error handlers
def handle_401(request, response, exception):
logging.exception(exception)
response.write("401 Error")
response.set_status(401)
def handle_403(request, response, exception):
logging.exception(exception)
response.write("403 Error")
response.set_status(403)
def handle_404(request, response, exception):
logging.exception(exception)
response.write("404 Error")
response.set_status(404)
def handle_500(request, response, exception):
logging.exception(exception)
response.write("500 Error")
response.set_status(500)
# add the error handlers
bare_app.error_handlers[401] = handle_401
bare_app.error_handlers[403] = handle_403
bare_app.error_handlers[404] = handle_404
bare_app.error_handlers[500] = handle_500
bare_app.router.add((r'/', HomeHandler))
app = bare_app
edit:
use self.abort() instead of self.error()
http://webapp-improved.appspot.com/guide/exceptions.html#abort
you can see the difference in the source code:
http://code.google.com/p/webapp-improved/source/browse/webapp2.py#574
while self.error() sets the status code but clears the response, self.abort() executes the function that takes care of the error handling.