cherrypy._cperror module

Exception classes for CherryPy.

CherryPy provides (and uses) exceptions for declaring that the HTTP response should be a status other than the default “200 OK”. You can raise them like normal Python exceptions. You can also call them and they will raise themselves; this means you can set an HTTPError or HTTPRedirect as the request.handler.

Redirecting POST

When you GET a resource and are redirected by the server to another Location, there’s generally no problem since GET is both a “safe method” (there should be no side-effects) and an “idempotent method” (multiple calls are no different than a single call).

POST, however, is neither safe nor idempotent–if you charge a credit card, you don’t want to be charged twice by a redirect!

For this reason, none of the 3xx responses permit a user-agent (browser) to resubmit a POST on redirection without first confirming the action with the user:

300

Multiple Choices

Confirm with the user

301

Moved Permanently

Confirm with the user

302

Found (Object moved temporarily)

Confirm with the user

303

See Other

GET the new URI; no confirmation

304

Not modified

for conditional GET only; POST should not raise this error

305

Use Proxy

Confirm with the user

307

Temporary Redirect

Confirm with the user

308

Permanent Redirect

No confirmation

However, browsers have historically implemented these restrictions poorly; in particular, many browsers do not force the user to confirm 301, 302 or 307 when redirecting POST. For this reason, CherryPy defaults to 303, which most user-agents appear to have implemented correctly. Therefore, if you raise HTTPRedirect for a POST request, the user-agent will most likely attempt to GET the new URI (without asking for confirmation from the user). We realize this is confusing for developers, but it’s the safest thing we could do. You are of course free to raise HTTPRedirect(uri, status=302) or any other 3xx status if you know what you’re doing, but given the environment, we couldn’t let any of those be the default.

Custom Error Handling

refman/cperrors.gif

Anticipated HTTP responses

The ‘error_page’ config namespace can be used to provide custom HTML output for expected responses (like 404 Not Found). Supply a filename from which the output will be read. The contents will be interpolated with the values %(status)s, %(message)s, %(traceback)s, and %(version)s using plain old Python string formatting.

_cp_config = {
    'error_page.404': os.path.join(localDir, "static/index.html")
}

Beginning in version 3.1, you may also provide a function or other callable as an error_page entry. It will be passed the same status, message, traceback and version arguments that are interpolated into templates:

def error_page_402(status, message, traceback, version):
    return "Error %s - Well, I'm very sorry but you haven't paid!" % status
cherrypy.config.update({'error_page.402': error_page_402})

Also in 3.1, in addition to the numbered error codes, you may also supply “error_page.default” to handle all codes which do not have their own error_page entry.

Unanticipated errors

CherryPy also has a generic error handling mechanism: whenever an unanticipated error occurs in your code, it will call Request.error_response to set the response status, headers, and body. By default, this is the same output as HTTPError(500). If you want to provide some other behavior, you generally replace “request.error_response”.

Here is some sample code that shows how to display a custom error message and send an e-mail containing the error:

from cherrypy import _cperror

def handle_error():
    cherrypy.response.status = 500
    cherrypy.response.body = [
        "<html><body>Sorry, an error occurred</body></html>"
    ]
    sendMail('error@domain.com',
             'Error in your web app',
             _cperror.format_exc())

@cherrypy.config(**{'request.error_response': handle_error})
class Root:
    pass

Note that you have to explicitly set response.body and not simply return an error message as a result.

exception cherrypy._cperror.CherryPyException[source]

Bases: Exception

A base class for CherryPy exceptions.

exception cherrypy._cperror.HTTPError(status=500, message=None)[source]

Bases: CherryPyException

Exception used to return an HTTP error code (4xx-5xx) to the client.

This exception can be used to automatically send a response using a http status code, with an appropriate error page. It takes an optional status argument (which must be between 400 and 599); it defaults to 500 (“Internal Server Error”). It also takes an optional message argument, which will be returned in the response body. See RFC2616 for a complete list of available error codes and when to use them.

Examples:

raise cherrypy.HTTPError(403)
raise cherrypy.HTTPError(
    "403 Forbidden", "You are not allowed to access this resource.")
code = None

The integer HTTP status code.

get_error_page(*args, **kwargs)[source]
classmethod handle(exception, status=500, message='')[source]

Translate exception into an HTTPError.

reason = None

The HTTP Reason-Phrase string.

set_response()[source]

Modify cherrypy.response status, headers, and body to represent self.

CherryPy uses this internally, but you can also use it to create an HTTPError object and set its output without raising the exception.

status = None

The HTTP status code.

May be of type int or str (with a Reason-Phrase).

exception cherrypy._cperror.HTTPRedirect(urls, status=None, encoding=None)[source]

Bases: CherryPyException

Exception raised when the request should be redirected.

This exception will force a HTTP redirect to the URL or URL’s you give it. The new URL must be passed as the first argument to the Exception, e.g., HTTPRedirect(newUrl). Multiple URLs are allowed in a list. If a URL is absolute, it will be used as-is. If it is relative, it is assumed to be relative to the current cherrypy.request.path_info.

If one of the provided URL is a unicode object, it will be encoded using the default encoding or the one passed in parameter.

There are multiple types of redirect, from which you can select via the status argument. If you do not provide a status arg, it defaults to 303 (or 302 if responding with HTTP/1.0).

Examples:

raise cherrypy.HTTPRedirect("")
raise cherrypy.HTTPRedirect("/abs/path", 307)
raise cherrypy.HTTPRedirect(["path1", "path2?a=1&b=2"], 301)

See Redirecting POST for additional caveats.

default_status = 303
encoding = 'utf-8'

The encoding when passed urls are not native strings.

set_response()[source]

Modify cherrypy.response status, headers, and body to represent self.

CherryPy uses this internally, but you can also use it to create an HTTPRedirect object and set its output without raising the exception.

property status

The integer HTTP status code to emit.

urls = None

The list of URL’s to emit.

exception cherrypy._cperror.InternalRedirect(path, query_string='')[source]

Bases: CherryPyException

Exception raised to switch to the handler for a different URL.

This exception will redirect processing to another path within the site (without informing the client). Provide the new path as an argument when raising the exception. Provide any params in the querystring for the new URL.

exception cherrypy._cperror.NotFound(path=None)[source]

Bases: HTTPError

Exception raised when a URL could not be mapped to any handler (404).

This is equivalent to raising HTTPError("404 Not Found").

cherrypy._cperror._be_ie_unfriendly(status)[source]
cherrypy._cperror.bare_error(extrabody=None)[source]

Produce status, headers, body for a critical error.

Returns a triple without calling any other questionable functions, so it should be as error-free as possible. Call it from an HTTP server if you get errors outside of the request.

If extrabody is None, a friendly but rather unhelpful error message is set in the body. If extrabody is a string, it will be appended as-is to the body.

cherrypy._cperror.clean_headers(status)[source]

Remove any headers which should not apply to an error response.

cherrypy._cperror.format_exc(exc=None)[source]

Return exc (or sys.exc_info if None), formatted.

cherrypy._cperror.get_error_page(status, **kwargs)[source]

Return an HTML page, containing a pretty error response.

status should be an int or a str. kwargs will be interpolated into the page template.