在C#中捕获Ironpython异常

时间:2009-03-05 11:14:24

标签: exception ironpython

我在C#中嵌入了IronPython 2.0。在IronPython中,我用:

定义了我自己的异常
def foobarException(Exception):
    pass 

并将其提升到:

raise foobarException( "This is the Exception Message" )

现在在C#中,我有:

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"
}

4 个答案:

答案 0 :(得分:16)

当您从C#捕获IronPython异常时,可以使用Python引擎格式化回溯:

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

您可以从回溯中提取异常名称。否则,您将不得不调用IronPython托管API直接从异常实例中检索信息。 engine.Operations为这些交互提供了有用的方法。

答案 1 :(得分:3)

IronPython将.NET异常映射到Python异常的方式并不总是直截了当的;许多异常报告为SystemError(尽管如果导入.NET异常类型,则可以在except子句中指定)。您可以使用

获取异常的Python类型
type(e).__name__

如果您需要.NET异常类型,请确保模块中有import clr。它使.NET属性可用于对象,例如字符串上的ToUpper()方法。然后,您可以使用.clsException属性访问.NET异常:

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

打印:

ZeroDivisionError      # the python exception
DivideByZeroException  # the corresponding .NET exception

捕获所需特定.NET异常的示例:

from System import DivideByZeroException
try:
    1/0
except DivideByZeroException:
    print 'caught'

答案 2 :(得分:1)

我的最终解决方案是:

我在C#中有一个结果类,它被传递给我的ironpython代码。在Ironpython中,我用所有计算值填充结果类。我刚刚在这个类中添加了一个成员变量IronPythonExceptionName。现在我只是在IronPython中进行一次简单的尝试:

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

答案 3 :(得分:0)

假设您使用.NET等效编译器编译了python代码,那么您将拥有一个静态类型,这就是异常。如果此异常是公共的(导出类型),那么您在项目中引用包含python代码的程序集,并在某个python名称空间中挖掘类型foobarException。这样C#就可以输入匹配该异常。这是你能够做到这一点的唯一方法。