views:

1110

answers:

4

I'm embedding IronPython 2.0 in c#. In IronPython I defined my own exception with:

def foobarException(Exception):
    pass

and raise it somewhere with: raise foobarException( "This is the Exception Message" )

now in c# I have:

try
{
   callIronPython();
}
catch (Exception e)
{
  // How can I determine here the name (foobarException) of the Exception that is 
  // thrown from IronPython??   
  // With e.Message I get: "This is the Exception Message"


}
A: 

Assuming that you compiled your python code with the .NET equivalent compiler you would have a static type which is just that exception. If this exception is public (exported type) then you reference the assembly that contains your python code in your project and dig up the type foobarException in some python namespace. That way C# will be able to type match that exception. This is the only way you can do that properly.

John Leidegren
A: 

The way IronPython maps .NET exceptions to Python ones isn't always straightforward - a lot of exceptions are reported as SystemError (although if you import the .NET exception type you can specify that in the except clause). You can get the Python type of the exception using:

type(e).__name__

If you want the .NET exception type, make sure you have import clr in the module (which makes .NET attributes available on objects (like the ToUpper method on strings)). Then you can get hold of the .NET exception using the .clsException attribute:

import clr
try:
    1/0
except Exception, e:
    print type(e).__name__
    print type(e.clsException).__name__

prints:

ZeroDivisionError (the python exception)
DivideByZeroException (the corresponding .NET exception)

An example of catching the specific .NET exception you want:

from System import DivideByZeroException
try:
    1/0
except DivideByZeroException:
    print 'caught'
wilberforce
+8  A: 

When you catch an IronPython exception from C# you can use the Python engine to format the traceback:

catch (Exception e)
{
    ExceptionOperations eo = _engine.GetService<ExceptionOperations>(); 
    string error = eo.FormatException(e); 
    Console.WriteLine(error);
}

You can pull the exception name out of the traceback. Otherwise you will have to call into the IronPython hosting API to retrieve information directly from the exception instance. engine.Operations has useful methods for these kinds of interactions.

fuzzyman
+1  A: 

My final solution was:

I have a result class in C# which is passed to my ironpython code. In Ironpython I fill the result class with all my computed values. To this class I just added a member variable IronPythonExceptionName. Now I just have a simple try in IronPython:

try: 
    complicatedIronPythonFunction()
except Exception, inst:
    result.IronPythonExceptionName = inst.__class__.__name__
    raise inst
foobar