Перехват исключения Ironpython в C#
-
03-07-2019 - |
Вопрос
Я встраиваю IronPython 2.0 в C#.В IronPython я определил собственное исключение с помощью:
def foobarException(Exception):
pass
и поднимите его где-нибудь с помощью:
raise foobarException( "This is the Exception Message" )
Теперь в С# у меня есть:
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"
}
Решение 3
Мое окончательное решение было:
У меня есть класс результата в C #, который передается в мой код Ironpython. В Ironpython я заполняю класс результата всеми своими вычисленными значениями. В этот класс я только что добавил переменную-член IronPythonExceptionName. Теперь у меня есть простая попытка в IronPython:
try:
complicatedIronPythonFunction()
except Exception, inst:
result.IronPythonExceptionName = inst.__class__.__name__
raise inst
Другие советы
Когда вы ловите исключение IronPython из C #, вы можете использовать движок Python для форматирования трассировки:
catch (Exception e)
{
ExceptionOperations eo = _engine.GetService<ExceptionOperations>();
string error = eo.FormatException(e);
Console.WriteLine(error);
}
Вы можете извлечь имя исключения из трассировки. В противном случае вам придется вызвать API-интерфейс хостинга IronPython, чтобы получить информацию непосредственно из экземпляра исключения. engine.Operations
имеет полезные методы для такого рода взаимодействий.
Способ, которым IronPython сопоставляет исключения .NET с исключениями Python, не всегда прост;о многих исключениях сообщается как SystemError
(хотя если вы импортируете тип исключения .NET, вы можете указать это в except
пункт).Вы можете получить тип исключения Python, используя
type(e).__name__
Если вам нужен тип исключения .NET, убедитесь, что у вас есть import clr
в модуле.Он делает атрибуты .NET доступными для объектов, таких как ToUpper()
метод для строк.Затем вы можете получить доступ к исключению .NET, используя .clsException
атрибут:
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'
Предполагая, что вы скомпилировали свой код Python с помощью эквивалентного компилятора .NET, у вас будет статический тип, который является именно этим исключением. Если это исключение является общедоступным (экспортируемый тип), тогда вы ссылаетесь на сборку, которая содержит ваш код Python в вашем проекте, и выявляете тип foobarException в некотором пространстве имен Python. Таким образом, C # сможет напечатать соответствие этому исключению. Это единственный способ сделать это правильно.