2009-03-05 7 views
6

J'intègre IronPython 2.0 en C#. Dans IronPython, je définissais ma propre exception avec:Catching Ironpython Exception in C#

def foobarException(Exception): 
    pass 

et l'élever quelque part avec:

raise foobarException("This is the Exception Message") 

Maintenant en C#, je:

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

Avez-vous essayé cela avec un débogueur? Vous devriez voir le type d'exception ou l'exception interne, ou partout où l'exception python est stockée. – OregonGhost

+0

oui j'ai essayé avec un débogueur, mais je n'ai pas pu le trouver. Le fait est que cela a fonctionné avec IronPython 1.1. Quand je me souviens correctement dans e.Data ["PythonExceptionInfo"] il y avait réellement le python exception.message. Et dans e.Message il y avait le nom de l'Exception. – foobar

Répondre

1

Ma solution finale était:

J'ai une classe de résultat en C# qui est passé à mon code IronPython. Dans Ironpython, je remplis la classe résultat avec toutes mes valeurs calculées. Pour cette classe, je viens d'ajouter une variable membre IronPythonExceptionName. Maintenant, j'ai juste un essai simple dans IronPython:

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

En supposant que vous avez compilé votre code python avec le compilateur équivalent .NET vous auriez un type statique qui est juste cette exception. Si cette exception est publique (type exporté) alors vous référencez l'assembly qui contient votre code python dans votre projet et déterrez le type foobarException dans un espace de nom python. De cette façon, C# sera capable de taper cette exception. C'est la seule façon de le faire correctement.

3

La façon dont IronPython mappe les exceptions .NET à celles de Python n'est pas toujours simple; beaucoup d'exceptions sont signalées comme SystemError (bien que si vous importez le type d'exception .NET, vous pouvez spécifier cela dans la clause except). Vous pouvez obtenir le type Python de l'exception en utilisant

type(e).__name__ 

Si vous voulez que le type d'exception .NET, assurez-vous que vous avez import clr dans le module. Il rend les attributs .NET disponibles sur les objets, comme la méthode ToUpper() sur les chaînes. Ensuite, vous pouvez accéder à l'exception .NET en utilisant l'attribut .clsException:

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

impressions:

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

Un exemple d'attraper l'exception .NET spécifique que vous souhaitez:

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

Lorsque vous récupérer une exception IronPython de C#, vous pouvez utiliser le moteur Python pour formater le retraçage:

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

Vous pouvez retirer le nom de l'exception du retraçage. Sinon, vous devrez appeler l'API d'hébergement IronPython pour récupérer des informations directement à partir de l'instance d'exception. engine.Operations a des méthodes utiles pour ces types d'interactions.

+0

FormatException n'est utile que pour SyntaxErrorException, il régurgite simplement Exception.Message pour tous les autres. – Tergiver