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 the name (foobarException) of the Exception
// that is thrown from IronPython?
// With e.Message, I get "This is the Exception Message"
}
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.
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. It makes .NET attributes available on objects, like the ToUpper()
method on strings. Then you can access 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'
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
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.