error.py
author Tero Marttila <terom@fixme.fi>
Mon, 16 Feb 2009 02:49:06 +0200
changeset 135 19ff083c2870
parent 134 fbccc1648d79
child 136 c69a176b3620
permissions -rw-r--r--
pimp mah error messages, it has a full link to the Trac with pre-filled title, traceback, url, hg revision fields
"""
    Build error messages
"""

import traceback, sys, cgi, urllib

def build_error (exc_info=None, env=None) :
    """
        Dumps out a raw traceback of the given/current exception to stdout.

        If request_env, it should be a environment dict, like under WSGI, and will be used to display additional info
        about the request.

        Returns a (status, content-type, body) tuple, with all components being non-unicode strs.
    """

    # default for exc_info is current exception
    if not exc_info :
        exc_info = sys.exc_info()

    # request URL?
    if env :
        try :
            from qmsk.web.http import request_url

            url = request_url(env)

        except :
            # ignore
            url = None
    else :
        url = None

    # working copy path?
    try :
        from config import HG_WC_PATH

        wc_path = HG_WC_PATH

    except :
        # a good guess
        wc_path = '.'
    
    # version?
    try :
        from version import version_string

        version = version_string(wc_path)
    
    except :
        version = None
    
    # the exception type
    exception_str = traceback.format_exception_only(*exc_info[:2])[-1][:255]

    # the exception traceback
    traceback_lines = traceback.format_exception(*exc_info)

    # XXX: make this configureable
    trac_url = "http://projects.qmsk.net/irclogs2/trac"
    
    # ticket list
    query_url = "%s/query" % trac_url

    # submit ticket
    submit_args = dict(type='defect')

    if url :
        submit_args['url'] = url

    if version :
        submit_args['revision'] = version
    
    if exception_str :
        submit_args['summary'] = exception_str

    if traceback_lines :
        # this is big
        submit_args['description'] = """\
[Insert any additional information here]


= Traceback =
{{{
%s
}}}""" % ''.join(traceback_lines)
    
    # the trac newticket URL
    submit_url = "%s/newticket?%s" % (trac_url, '&amp;'.join('%s=%s' % (urllib.quote(k), urllib.quote(v)) for k, v in submit_args.iteritems()))

    # return
    return ('500 Internal Server Error', 'text/html; charset=UTF-8', ("""\
<html><head><title>500 Internal Server Error</title></head><body>
<h1>Oops!</h1>
<p>
    An error occured, which was not logged, and will not be reported to anybody. It might be your fault, or it might be
    mine. 
</p>
<p>
    You can try poking the administrator of this site to see if they respond, or submit a defect ticket at the <a href="%(query_url)s">Project Trac</a>, using the following link:
</p>
<pre>
    <a href="%(submit_url)s">%(submit_url_short)s</a>
</pre>
<h2>Details:</h2>
<pre>%(traceback)s</pre>
</body></html>""" % dict(
        traceback           = cgi.escape(''.join(traceback_lines)),
        query_url           = query_url,
        submit_url          = submit_url,
        submit_url_short    = submit_url[:120] + '...'
    )).encode('utf-8'))