Warning: Can't synchronize with repository "(default)" (Unsupported version control system "svn": No module named svn). Look in the Trac log for more information.

Ticket #86 (closed defect: fixed)

Opened 14 years ago

Last modified 12 years ago

Nicer error handler for quickstarted projects

Reported by: kevin Owned by:
Priority: normal Milestone: 0.9a5
Component: TurboGears Version:
Severity: normal Keywords:
Cc: ianb@…

Description

A better error handling page (one that looks nicer and is more usable from the get-go, plus also illustrates how to do an error handler) would be a good addition to quickstart.

Change History

comment:1 Changed 14 years ago by gunfighter

 This post to the newsgroup has an idea embedded in it:

"One particular thought is to have the error handling page load the Simple Description, TraceBack?, and any other pertinent information in JSON format. Perhaps display the true error in a simple format (e.g. "No such method comple in model.py on line 123") and have a "Click here for traceback" link that would display the full traceback information."

comment:2 Changed 14 years ago by kevin

  • Milestone set to 0.9

comment:3 Changed 14 years ago by ianb@…

Don't get too crazy with JSON. A formatted traceback in a hidden div will work just as well.

comment:4 Changed 13 years ago by Aaron Digulla

Is there a way to see the python code which Kid produces?

As is, you can have two types of errors right now, which are hard to track down:

  1. Errors in python code in kid templates. Since Kid will reformat the code, the line numbers won't match anymore, so it's impossible to find the line from the trace.
  1. Errors which happen during the processing of the lists, for example, when you put a generator in there.

For the former, I'd propose to add an exception handler in the kid template wrapper code (i.e. the code which compiles the kid template). If an error happens, it should process the template again but this time, keep the intermediate python module and display that (with line numbers) next to the trace.

For the latter, kid should register some information about generators when it notices them (for example, the stack trace at the point of registration). Since this is an expensive operation, there should be a flag (ideally toggable during runtime) which (de-)activates this behaviour.

comment:5 Changed 13 years ago by michele

I think this is linked to #16 that has some useful information from Ian Bicking regarding Kid.

I also add:  http://blog.ianbicking.org/ajaxy-exception-catching.html

comment:6 Changed 13 years ago by kevin

  • Keywords develix added

This ticket is not for covering Kid error handling improvements, which are more involved. This ticket is all about creating a nice error handler and error template for new quickstarted projects. So, it should look good and be use (perhaps providing the traceback in a hidden div as Ian suggests).

comment:7 Changed 13 years ago by michele

Yep, sorry for creating confusion between two different issues (#16 and this).

comment:8 Changed 13 years ago by Daniel Holth <dholth@…>

Here is something adapted from the CherryPy? wiki that anyone can use right now. Differences from the default controller include the error handling function and required import functions.

It uses cgitb to generate the traceback.

import turbogears
import StringIO
import cgitb
import cherrypy
import sys
from turbogears import controllers

class Root(controllers.Root):
    @turbogears.expose(html="wiki20.templates.welcome")
    def index(self):
        import time
        return dict(now=time.ctime())

    def _cpOnError(self):
        err = sys.exc_info()
        if cherrypy.config.get('server.environment') == 'development':
            sio = StringIO.StringIO()
            message = cgitb.html(err)
            cherrypy.response.headerMap['Content-Type'] = 'text/html'
            cherrypy.response.body = [message]
        else:
            print cherrypy.server.environment
            cherrypy.response.body = ['Error: ' + str(err[0])]

comment:9 Changed 13 years ago by kevin

What I'm angling for here is basically to include a default _cp_on_error and a nice looking template to get people going.

comment:10 Changed 13 years ago by oefe

  • Owner changed from anonymous to oefe

That's what I'm aiming for at the moment.

However, ideally we should just be able to paste Ian's excellent work (paste.exceptions resp paste.evalexception). C'mon, paste is already in TurboGears/thirdparty - why reinvent the wheel?

comment:11 Changed 13 years ago by kevin

  • Keywords develix removed
  • Milestone changed from 0.9 to 1.1

Hmm... we'll be able to use evalexception directly in First Class, due to the heightened support for WSGI configuration.

However, I think there needs to be a different kind of error handling page for production use, which lends even more weight to the argument that this should be configured. I'm going to move this ticket to First Class so that we can address it there.

comment:12 Changed 13 years ago by simon

Wouldn't it be better to just enhance Ian's Ajaxy Exception with some sort of "production mode". Anyone using it is bound to come across the same issue, why not solve it once and for all?

comment:13 Changed 13 years ago by michele

We can easily get EvalException? even on 0.9 using this recipe from dowski:

 http://www.cherrypy.org/wiki/CustomServers22

comment:14 Changed 13 years ago by oefe

  • Owner oefe deleted

comment:15 Changed 13 years ago by ianb@…

  • Cc ianb@… added

Yes, evalexception works fine with CP as long as it is at the root. There might be some problems if it is placed somewhere other than the root of the site due to some CP WSGI issues, but it's quite possible that Christian fixed this since I last tried it.

paste.exceptions provides a more static view, as well as options for emailing and logging. I use this for production code. It would be nice if it had the same local-scope inspection like evalexception has.

Stylistically Pylons has made additions to both views. I haven't had a chance to integrate these, in part because I want to make it more generic, so that (for instance) TG could add its own look. Though just prettifying it regardless would be nice.

There's also several ways to extend the error reports, e.g., traceback_supplement paste.exceptions.errormiddleware has an example of this, and Paste WebKit? shows a framework-specific extension:  http://svn.pythonpaste.org/Paste/WebKit/trunk/paste/webkit/wkservlet.py (the WebKit? one shows the values of servlet instance variables, and the form submission). TG can extend exception reports in similar ways.

comment:16 Changed 13 years ago by godoy

Whatever the solution is, I'd like to remember that it should provide the less ammount of information possible anywhere outside the logfile while in production mode. This is to avoid risky data from being visible to an attacker or some user with a less priviledged account. Having this configurable is interesting as well.

comment:17 Changed 13 years ago by ianb@…

paste.exceptions only displays anything interesting when debug mode is on.

For nice public error pages, paste.errordocument also can do internal redirects so that all 500 errors can be processed the same way regardless of whether they come from TurboGears or any other WSGI app.

comment:18 Changed 13 years ago by mgood

I've added EvalException to my start-package.py file based on the CherryPy? example. Simply replace the last line (cherrypy.server.start()) with:

from cherrypy._cpwsgi import wsgiApp, CPHTTPRequest
from cherrypy._cpwsgiserver import CherryPyWSGIServer

class SimpleWSGIServer(CherryPyWSGIServer):
    """A WSGI server that accepts a WSGI application as a parameter."""
    RequestHandlerClass = CPHTTPRequest
    
    def __init__(self):
        conf = cherrypy.config.get
        wsgi_app = wsgiApp
        if conf('server.environment') == 'development':
            try:
                from paste.evalexception.middleware import EvalException
            except ImportError:
                pass
            else:
                wsgi_app = EvalException(wsgi_app, global_conf={})
                cherrypy.config.update({'server.throw_errors':True})
        bind_addr = (conf("server.socket_host"), conf("server.socket_port"))
        CherryPyWSGIServer.__init__(self, bind_addr, wsgi_app,
                                    conf("server.thread_pool"),
                                    conf("server.socket_host"),
                                    request_queue_size = conf(
                                        "server.socket_queue_size"),
                                    )

cherrypy.server.start(server=SimpleWSGIServer())

The EvalException middleware is only enabled in development mode, and ignores it if Paste is not installed.

comment:19 Changed 13 years ago by kevin

  • Status changed from new to closed
  • Resolution set to fixed
  • Milestone changed from 1.1 to 0.9a5

I've committed mgood's approach in [1293]. Thanks!

Because it looks, well, unattractive, I've got it hidden behind a tg.fancy_exception option (default is false). Once we've spruced it up, this will become the default.

comment:20 Changed 13 years ago by ianb@…

Note that Pylons is styling Paste's exception reports. You can see their stuff here:  http://pylonshq.com/project/pylonshq/browser/Pylons/trunk/pylons/error.py -- I believe James Gardner wrote most of that. Potentially some of it could be pushed back into Paste so it's easier to apply.

Note: See TracTickets for help on using tickets.