2009-03-05 19 views
6

Sto incorporando IronPython 2.0 in C#. In IronPython, ho definito la mia eccezione con:Catching Ironpython Eccezione in C#

def foobarException(Exception): 
    pass 

e sollevare da qualche parte con:

raise foobarException("This is the Exception Message") 

Ora in C#, ho:

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

Hai provato con un debugger? Dovresti vedere il tipo di eccezione o l'eccezione interna, o ovunque sia memorizzata l'effettiva eccezione python. – OregonGhost

+0

sì, ho provato con un debugger, ma non sono riuscito a trovarlo. Il fatto è che ha funzionato con IronPython 1.1. Quando ricordo correttamente in e.Data ["PythonExceptionInfo"] c'era in realtà il file python exception.message. E in e.Message c'era il nome dell'eccezione. – foobar

risposta

1

La mia soluzione finale era:

Ho una classe risultato in C# che è passato al mio codice IronPython. In Ironpython riempio la classe dei risultati con tutti i miei valori calcolati. A questa classe ho appena aggiunto una variabile membro IronPythonExceptionName. Ora ho solo una prova semplice in IronPython:

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

Supponendo che si è compilato il tuo codice Python con il compilatore equivalente .NET avresti un tipo statico che è proprio quell'eccezione. Se questa eccezione è pubblica (tipo esportato), fai riferimento all'assembly che contiene il tuo codice python nel tuo progetto e recupera il tipo foobarException in qualche spazio dei nomi python. In questo modo C# sarà in grado di digitare questa eccezione. Questo è l'unico modo per farlo correttamente.

3

Il modo in cui IronPython esegue il mapping delle eccezioni .NET a quelle di Python non è sempre semplice; molte eccezioni sono segnalate come SystemError (anche se si importa il tipo di eccezione .NET è possibile specificare che nella clausola except). È possibile ottenere il tipo di Python dell'eccezione mediante

type(e).__name__ 

Se si desidera che il tipo di eccezione .NET, assicurarsi di avere import clr nel modulo. Rende disponibili gli attributi .NET sugli oggetti, come il metodo ToUpper() sulle stringhe. Poi si può accedere l'eccezione .NET utilizzando l'attributo .clsException:

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

stampe:

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

Un esempio di catturare l'eccezione specifica .NET che si desidera:

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

Quando si cattura un'eccezione IronPython da C#, puoi utilizzare il motore Python per formattare il traceback:

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

È possibile estrarre il nome dell'eccezione dal traceback. In caso contrario, sarà necessario chiamare l'API di hosting IronPython per recuperare le informazioni direttamente dall'istanza dell'eccezione. engine.Operations ha metodi utili per questi tipi di interazioni.

+0

FormatException è utile solo per SyntaxErrorException, ma rigurgita solo Exception.Message per gli altri. – Tergiver