Handling Unhandled Exceptions

From IronPython Cookbook

In a Windows Forms application, you might want your code to catch all otherwise unhandled exceptions. You may want to do some clean-up, or present the information about the crash a bit more gracefully to the user.

This is done with the Application.ThreadException event and the ThreadExceptionEventHandler delegate.

Setting up exception handling must be done before any controls are created.

In the code below, an exception handler is setup, which will be given information about all unhandled exceptions that occur. It creates a form with a button; pressing the button raises an exception (inside a nested function so that the traceback is more interesting).

Getting proper information about an exception raised in Python code is tricky. Three different approaches are shown inside the exceptionHandler function:

import clr
clr.AddReference('System.Windows.Forms')

from System.Windows.Forms import Application, Form, Button, UnhandledExceptionMode
from System.Threading import ThreadExceptionEventHandler


# Exception handling must be setup *before* creating any controls

def exceptionHandler(sender, event):
    # Big long nasty .NET exception
    print event.Exception
    print
    
    # The Exception object (not much information)
    # sys.exc_info() doesn't return anything useful here
    e = event.Exception.Data['PythonExceptionInfo']
    print e
    
    # A hack suggested by Dino Viehland which
    # gets you a nicely formatted exception
    from IronPython.Hosting import PythonEngine
    pyE = PythonEngine()
    print pyE.FormatException(event.Exception)


Application.ThreadException += ThreadExceptionEventHandler(exceptionHandler)
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException)


def OuterDie(sender, event):
    def InnerDie():
        # Apologies to all Mervins everywhere
        raise NameError('Mervin is a silly name')
    InnerDie()
    
f = Form(Text='Exception Example')
b = Button(Text='Click Me')
b.Click += OuterDie
b.Parent = f

Application.Run(f)

For IronPython 2.0, the code to format the exception from a PythonEngine is slightly different:

import clr
clr.AddReference('IronPython')
from IronPython.Hosting import PythonEngine
PythonEngine.CurrentEngine.FormatException(someException)

In IronPython 2.0 you don't need to (and can't - yet) create a new Python engine. You no longer automatically have references to the IronPython's dlls, which is why you need the AddReference step as well.


Back to Contents.

TOOLBOX
LANGUAGES