Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to catch all exceptions with CherryPy?

I use CherryPy to run a very simple web server. It is intended to process the GET parameters and, if they are correct, do something with them.

import cherrypy

class MainServer(object):
    def index(self, **params):
        # do things with correct parameters
        if 'a' in params:
            print params['a']

    index.exposed = True

cherrypy.quickstart(MainServer())

For example,

http://127.0.0.1:8080/abcde:

 404 Not Found

The path '/abcde' was not found.

Traceback (most recent call last):
  File "C:\Python27\lib\site-packages\cherrypy\_cprequest.py", line 656, in respond
    response.body = self.handler()
  File "C:\Python27\lib\site-packages\cherrypy\lib\encoding.py", line 188, in __call__
    self.body = self.oldhandler(*args, **kwargs)
  File "C:\Python27\lib\site-packages\cherrypy\_cperror.py", line 386, in __call__
    raise self
NotFound: (404, "The path '/abcde' was not found.")
Powered by CherryPy 3.2.4

I am trying to catch this exception and show a blank page because the clients do not care about it. Specifically, the result would be an empty body, no matter the url or query string that resulted in an exception.

I had a look at documentation on error handling cherrypy._cperror, but I did not find a way to actually use it.

Note: I gave up using CherryPy and found a simple solution using BaseHTTPServer (see my answer below)

like image 697
WoJ Avatar asked Dec 05 '13 09:12

WoJ


People also ask

How do you catch all exceptions in Python?

Try and Except Statement – Catching all Exceptions Try and except statements are used to catch and handle exceptions in Python. Statements that can raise exceptions are kept inside the try clause and the statements that handle the exception are written inside except clause.

Is CherryPy a MVC?

Bird's-Eye View of CherryPyIt also takes a modular approach, following the Model View Controller (MVC) pattern to build web services; therefore, it's fast and developer-friendly.

Is CherryPy a web server?

CherryPy comes with its own web (HTTP) server. That is why CherryPy is self-contained and allows users to run a CherryPy application within minutes of getting the library. The web server acts as the gateway to the application with the help of which all the requests and responses are kept in track.

What is CherryPy framework?

CherryPy is an object-oriented web application framework using the Python programming language. It is designed for rapid development of web applications by wrapping the HTTP protocol but stays at a low level and does not offer much more than what is defined in RFC 7231.


2 Answers

Choose what's most suitable for you: Default Methods, Custom Error Handling.

I don't think you should use BaseHTTPServer. If your app is that simple, just get a lightweight framework (e. g. Flask), even though it might be a bit overkill, OR stay low level but still within the WSGI standard and use a WSGI-compliant server.

like image 32
jwalker Avatar answered Sep 20 '22 00:09

jwalker


Docs somehow seem to miss this section. This is what I found while looking for detailed explanation for custom error handling from the source code.

Custom Error Handling

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('[email protected]',
             '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.

like image 124
Raghava Dhanya Avatar answered Sep 18 '22 00:09

Raghava Dhanya