Wrapping Tracebacks in HTML

Credit: Dirk Holtwick

Problem

In a CGI (or other web-based) program, you want to display tracebacks in the resulting HTML pages (not on sys.stderr, where tracebacks normally go), using HTML-compatible markup.

Solution

The format_tb and format_exception functions from the traceback module give us traceback information in string form, so we can return it to our caller, optionally escaped so it is printable within an HTML document:

def ErrorMsg(escape=1):
    """
    returns: string

    simulates a traceback output, and, if argument escape is set to 1 (true),
    the string is converted to fit into HTML documents without problems.
    """
    import traceback, sys, string

    limit = None
    type, value, tb = sys.exc_info(  )
    list = traceback.format_tb(tb, limit
        ) + traceback.format_exception_only(type, value)
    body = "Traceback (innermost last):\n" + "%-20s %s" % (
        string.join(list[:-1], ""), list[-1] )
    if escape:
        import cgi
        body = '\n<PRE>'+cgi.escape(body)+'</PRE>\n'
    return body

if _ _name_ _=="_ _main_ _":
    try:
        1/0
    except:
        print ErrorMsg(  )

Discussion

Well-structured CGI scripts and other web programs first write their output into something like a StringIO instance and then write it out. Therefore, this recipe may be helpful, as it returns error information as a multiline string that you can add to the appropriate StringIO instance in such cases. Normally, you would want some HTML markup to ensure that the error information is correctly displayed, and, by default, the ErrorMsg function in this recipe supplies this useful service as well (delegating it to the cgi.escape function, save for the wrapping of the whole escaped string into an HTML pre tag).

The recipe uses the sys.exc_info function to obtain information about the exception currently being handled (type, value, and a traceback object). The assumption is that this function is called from an exception handler (the except clause in a try/except statement). Then, the recipe calls the format_tb and format_exception functions from the traceback module to build the whole traceback information as a string to return to the caller, after optionally escaping it for HTML use.

This recipe can also be useful in other circumstances in which stderr may not be going to useful places, such as programs with GUIs—for example, you may want to dump error-trace information to a file for later examination. Of course, you would typically remove the HTML markup part of the recipe for such cases (or call the recipe’s ErrorMsg function with a parameter of 0).

See Also

Recipe 14.3 for another way of tracing calls that could be combined with this recipe; Recipe 14.5; the cgitb module, part of recent Python standard libraries, provides an extended version of this recipe with colorful formatting of tracebacks, links to the source code, etc.

Get Python Cookbook now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.