title: Google App Engine WebApp/Python Custom 404 Handler Implementation
body: <p>I'm using GAE, Google App Engine with Webapp using Python.</p>
  
  <p>I've been trying to implement a custom error handler, or template, or along those lines. GAE provides some documentation <a href="https://developers.google.com/appengine/docs/python/config/appconfig#Custom_Error_Responses" rel="nofollow noreferrer">here</a> however it doesn't provide enough in the example for implementation (for me).</p>
  
  <p>I've also looked at all these wonderful examples on another StackOverflow question <a href="https://stackoverflow.com/questions/189751/google-app-engine-and-404-error">here</a> - but cannot understand how to implement it into my current <b>main.py</b> file.</p>
  
  <pre><code>import os
  from google.appengine.ext import webapp
  from google.appengine.ext.webapp import util
  from google.appengine.ext.webapp import template
  
  class MainHandler(webapp.RequestHandler):
   def get (self, q):
      if q is None:
        q = 'static/index.html'
  
      path = os.path.join (os.path.dirname (__file__), q)
      self.response.headers ['Content-Type'] = 'text/html'
      self.response.out.write (template.render (path, {}))
  
  def main ():
    application = webapp.WSGIApplication ([('/(.*html)?', MainHandler)], debug=False)
    util.run_wsgi_app (application)
  
  if __name__ == '__main__':
    main ()
  </code></pre>
  
  <p>I've tried making another class, and implementing it before the <code>MainHandler</code> as well as a new <code>def</code> in the <code>MainHandler</code>. The only times I've gotten the 404 to display, it's displayed globally, meaning even the <code>index.html</code> file  was a "404".</p>
  
  <p>The last thing I tried was implementing something along the lines of:</p>
  
  <pre><code>if not os.path.exists (_file_):
   self.redirect(/static/error/404.html)
  </code></pre>
  
  <p>My <b>app.yaml</b> file is:</p>
  
  <pre><code>application: appname
  version: 1
  runtime: python
  api_version: 1
  
  error_handlers:
    - file: static/error/404.html
  
    - error_code: over_quota
      file: static/error/404.html
  
  handlers:
  - url: /(.*\.(gif|png|jpg|ico|js|css))
    static_files: \1
    upload: (.*\.(gif|png|jpg|ico|js|css))
  
  - url: /robots.txt
    static_files: robots.txt
    upload: robots.txt 
  
  - url: /favicon.ico
    static_files: favicon.ico
    upload: favicon.ico    
  
  - url: .*
    script: main.py
  </code></pre>
  
  <p>I cannot find any guides/tutorials to the implementation of the 404 handler, just code extracts.</p>
  
  <p>Much appreciated everyone!</p>
  
  <p>Edit:
  As per clarification from Hans below, <strong>I want to return a 404 when a file (or directory) is not present in the filesystem.</strong></p>
  
  <p>I've tried:</p>
  
  <pre><code>class ErrorHandler(webapp.RequestHandler):
    def get(self):
       if not os.path.isfile(_file_):
          self.redirect('/static/error/404.html')
  </code></pre>
  
  <p>to no avail. What's the correct implementation/syntax?</p>
  
  <p>Edit:
  To Voscausa</p>
  
  <pre><code>import os
  from google.appengine.ext import webapp
  from google.appengine.ext.webapp import util
  from google.appengine.ext.webapp import template
  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
  
  class MainHandler(webapp.RequestHandler):
    def get (self, q):
      if q is None:
        q = 'static/index.html'
  
      path = os.path.join (os.path.dirname (__file__), q)
      self.response.headers ['Content-Type'] = 'text/html'
      self.response.out.write (template.render (path, {}))
  
  def main ():
    application = webapp.WSGIApplication ([('/(.*html)?', MainHandler)], debug=True)
    util.run_wsgi_app (application)
  
  if __name__ == '__main__':
    main ()
  </code></pre>