2009. augusztus 27., csütörtök

TargetInvocationException eliminálás

Adott egy ilyen osztályunk:

class SomeClass
{
    public void SomeMethod()
    {
        int a = 0;
        int b = 1 / a;
    }
}
Ez sok mindent nem csinál, egy metódusa van, az is hülyeség, nullával próbál osztani.
Van hozzá egy ilyen kódunk:
var someClass = new SomeClass();
someClass.SomeMethod();
Ez meg meghívja azt a metódust. Eddig nem nagy mágia, szépen megkapjuk a magunk DivideByZeroException-jét.

De mi történik, ha valami miatt - jelen példában erre nem sok okunk van, de real-life sok lehet - nem a "hagyományos" módon, hanem reflection-nel, invokálással hívjuk a metódust?

var someClass = new SomeClass();
var methodInfo = typeof(SomeClass).GetMethod("SomeMethod", BindingFlags.Instance | BindingFlags.Public);

methodInfo.Invoke(someClass, null);
Az kiderül, hogy nullával való osztás problematikájára az invokált hívás se megoldás, viszont lényegesen cifrább kivételt kapunk: egy System.Reflection.TargetInvocationException-t, amibe ugyan be van csomagolva a DivideByZero is, de első látásra elég ilyesztő.

A TargetInvocationException néha lehet hasznos információ, de a saját tapasztalat azt mutatja, hogy inkább idegesítő. Az igazi hiba, a root cause nem ez, hanem a nullával osztás. A TargetInvocationException példányunk InnerException propertyjén keresztül viszont mindig elérhetjük az eredeti, hibát okozó kivételpéldányt. Nosza, invokáljunk így:

try
{
    methodInfo.Invoke(someClass, null);
}
catch (TargetInvocationException tiex)
{
    throw tiex.InnerException;
}
Visszakaptuk a DivideByZerót, sallangok nélkül, hurrá!

0 megjegyzés:

Megjegyzés küldése