Search code examples
pythoncherrypy

CherryPy: what is the difference between `error_page.default` vs. `error_page.404` config settings?


Let's say I want to display my own 404 & 500 pages, I've found 2 possibilities so far:

1: Using cherrypy.config.update

def error_page_404(status, message, traceback, version):
    return ('Error 404 Page not found')

def error_page_500(status, message, traceback, version):
    return ('Error:')

cherrypy.config.update({'error_page.404': error_page_404, 'error_page.500': error_page_500})
  1. Using _cp_config:
from cherrypy import _cperror

def handle_error():
    cherrypy.response.status = 500
    cherrypy.log("handle_error() called. Alarm!", "WEBAPP")
    cherrypy.response.body = ['Sorry, an error occured. The admin has been notified']
    error = _cperror.format_exc()

def error_page(status, message, traceback, version):
    cherrypy.log("error_page() called. Probably not very important.", "WEBAPP")
    return "Sorry, an error occured."

class Root: 
     _cp_config = { 
         'error_page.default': error_page, 
         'request.error_response': handle_error 
     } 

but is there a difference or a suggestion which is preferable to use?


Solution

  • request.error_response allows you to set a handler for processing of some unexpected errors, like your own exceptions raised from HTTP handlers. The callable that you'll set for this option will receive no arguments at all and you'll have to inspect sys.exc_info() for the details, to find out what happened. You'll also have to set cherrypy.response.status and cherrypy.response.body by yourself, explicitly in your error handler.

    If you want to modify the error response for HTTP error codes (when instances of cherrypy.HTTPError are raised, like raise cherrypy.NotFound), you can use error_page.default (catch-all) or error_page.404 (error-specific) for handling those errors. error_page options support both file path and callable values. In case of using a file path, the HTML template file can use the following substitution patterns: %(status)s, %(message)s, %(traceback)s, and %(version)s. If you opt-in to using a function, it'll receive those as arguments (callback(status, message, traceback, version)). The return value of this callable is then used HTTP response payload.

    As you can see, these approaches have different implications and different levels of flexibility and usability. Choose whatever works for you. Internally, the default request.error_response uses error_page settings to figure out what to return. So if you redefine request.error_response, it'll not use error_page.* settings unless you explicitly make it do so.

    See the docstring with some explanation here.