11
votes

Une bonne façon de trouver l'exception la plus intérieure?

Je travaille avec des classes qui, lors de la lancée, ont un arbre d'InneureException relativement profond. J'aimerais me connecter et agir à l'exception la plus interne qui est celle qui a la vraie raison du problème.

J'utilise actuellement quelque chose de similaire à xxx

Est-ce la bonne façon de gérer des arbres d'exception?


5 commentaires

Duplicaillier possible de Trouvez l'exception la plus intérieure sans utiliser de tandis que la boucle?


Si quelque chose, c'est l'autre que le double, celui de celui-ci et a la bonne réponse comme acceptée.


Question L'âge n'est pas toujours le critère directeur de la désignation d'un duplicata. Par exemple, considérez que l'autre question a plus de dix fois le nombre de points de vue que celui-ci le fait. En outre, la réponse acceptée ne reflète que l'opinion de la personne qui posa la question. Et enfin, veuillez noter que le La réponse la plus votée à l'autre question propose également getbaseException () , mais indique ensuite ses limites dans certaines situations.


Nombre de vues est discutable lorsqu'il y a un lien en double. Probablement c'est due au libellé de titre, j'ai donc édité le titre. Quoi qu'il en soit, signalez-le et laissez la communauté résoudre ce problème si vous le souhaitez.


Pour les critères à utiliser pour la fermeture d'un duplicata, sur Meta, voir Cette réponse et Cette réponse . Et d'ailleurs, des questions en double peuvent être très utiles en ce sens qu'ils peuvent guider les personnes à un sujet d'intérêt pouvant prendre des chemins quelque peu différents de ce sujet d'intérêt. Et une question fermée comme un duplicata peut toujours se lever (ou baisser) des votes et des commentaires. Cela s'applique également à ses réponses.


4 Réponses :


0
votes

dans un mot, oui. Je ne peux penser à aucune façon significativement meilleure ou différente de le faire. Sauf si vous vouliez l'ajouter comme une méthode d'extension à la place, mais c'est vraiment six d'une, une demi-douzaine de l'autre.


0 commentaires

4
votes

Vous pouvez utiliser le Méthode GetBaseException . Exemple très rapide:

try
{
    try
    {
        throw new ArgumentException("Innermost exception");
    }
    catch (Exception ex)
    {
        throw new Exception("Wrapper 1",ex);
    }
}
catch (Exception ex)
{
    // Writes out the ArgumentException details
    Console.WriteLine(ex.GetBaseException().ToString());
}


2 commentaires

+1, j'ai mieux aimé l'autre réponse, c'est pourquoi je l'ai accepté.


Assez juste, ne peut pas discuter avec ça :) Je pensais que je donnerais un exemple de code / harnais de test la démontrant en action.



12
votes

Je pense que vous pouvez obtenir l'exception la plus interne à l'aide du code suivant:

public static Exception getInnermostException(Exception e) { 
    return e.GetBaseException(); 
}


0 commentaires

0
votes

Il existe des exceptions pouvant avoir plusieurs causes racines (par exemple, AggregateException code> et réflectiontypeloadexception code>).

J'ai créé mon propre Classe Pour naviguer dans l'arborescence, puis différents visiteurs pour tout recueillir ou les causes de la racine. Exemples de sorties ici . Code pertinent Snippet ci-dessous. P>

public void Accept(ExceptionVisitor visitor)
{
    Read(this.exception, visitor);
}

private static void Read(Exception ex, ExceptionVisitor visitor)
{
    bool isRoot = ex.InnerException == null;
    if (isRoot)
    {
        visitor.VisitRootCause(ex);
    }

    visitor.Visit(ex);
    visitor.Depth++;

    bool isAggregateException = TestComplexExceptionType<AggregateException>(ex, visitor, aggregateException => aggregateException.InnerExceptions);
    TestComplexExceptionType<ReflectionTypeLoadException>(ex, visitor, reflectionTypeLoadException => reflectionTypeLoadException.LoaderExceptions);

    // aggregate exceptions populate the first element from InnerExceptions, so no need to revisit
    if (!isRoot && !isAggregateException)
    {
        visitor.VisitInnerException(ex.InnerException);
        Read(ex.InnerException, visitor);
    }

    // set the depth back to current context
    visitor.Depth--;
}

private static bool TestComplexExceptionType<T>(Exception ex, ExceptionVisitor visitor, Func<T, IEnumerable<Exception>> siblingEnumerator) where T : Exception
{
    var complexException = ex as T;
    if (complexException == null)
    {
        return false;
    }

    visitor.VisitComplexException(ex);

    foreach (Exception sibling in siblingEnumerator.Invoke(complexException))
    {
        visitor.VisitSiblingInnerException(sibling);
        Read(sibling, visitor);
    }

    return true;
}


0 commentaires