Package cherrypy :: Module _cperror
[hide private]
[frames] | no frames]

Module _cperror

source code

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 :class:`HTTPError<cherrypy._cperror.HTTPError>` or :class:`HTTPRedirect<cherrypy._cperror.HTTPRedirect>` as the :attr:`request.handler<cherrypy._cprequest.Request.handler>`.

.. _redirectingpost:

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 ===== ================================= ===========

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

.. image:: /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 <http://docs.python.org/2/library/stdtypes.html#string-formatting-operations>`_.

:

   _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 :func:`Request.error_response<cherrypy._cprequest.Request.error_response>` to set the response status, headers, and body. By default, this is the same output as :class:`HTTPError(500) <cherrypy._cperror.HTTPError>`. 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 occured</body></html>"
       ]
       sendMail('error@domain.com',
                'Error in your web app',
                _cperror.format_exc())

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

Note that you have to explicitly set :attr:`response.body <cherrypy._cprequest.Response.body>` and not simply return an error message as a result.

Classes [hide private]
  CherryPyException
A base class for CherryPy exceptions.
  TimeoutError
Exception raised when Response.timed_out is detected.
  InternalRedirect
Exception raised to switch to the handler for a different URL.
  HTTPRedirect
Exception raised when the request should be redirected.
  HTTPError
Exception used to return an HTTP error code (4xx-5xx) to the client.
  NotFound
Exception raised when a URL could not be mapped to any handler (404).
Functions [hide private]
 
clean_headers(status)
Remove any headers which should not apply to an error response.
source code
 
get_error_page(status, **kwargs)
Return an HTML page, containing a pretty error response.
source code
 
_be_ie_unfriendly(status) source code
 
format_exc(exc=None)
Return exc (or sys.exc_info if None), formatted.
source code
 
bare_error(extrabody=None)
Produce status, headers, body for a critical error.
source code
Variables [hide private]
  _HTTPErrorTemplate = '<!DOCTYPE html PUBLIC\n"-//W3C//DTD XHTM...
  _ie_friendly_error_sizes = {400: 512, 403: 256, 404: 512, 405:...
  __package__ = 'cherrypy'
Function Details [hide private]

get_error_page(status, **kwargs)

source code 

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.

bare_error(extrabody=None)

source code 

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.


Variables Details [hide private]

_HTTPErrorTemplate

Value:
'''<!DOCTYPE html PUBLIC
"-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"\
></meta>
    <title>%(status)s</title>
...

_ie_friendly_error_sizes

Value:
{400: 512,
 403: 256,
 404: 512,
 405: 256,
 406: 512,
 408: 512,
 409: 512,
 410: 256,
...