4 votes

Obtenir le vrai type d'exception contenu dans AggregateException

Une requête de base de données est effectuée dans une tâche qui a un CancellationToken de 59 secondes. Si la tâche est annulée, une TaskCanceledException est lancée. Mais cette exception est capturée dans le cadre d'une AggregateException. Je veux fournir un message d'erreur spécifique. Est-il possible de valider dans le code si l'exception réelle dans l'AggregateException est une TaskCancelationException?

4voto

Patrick Hofman Points 22166

Vous pouvez obtenir la liste des exceptions, ou utiliser la première si elle n'en contient qu'une :

var first = agg.InnerException; // juste la première

foreach (Exception ex in agg.InnerExceptions) // itérer sur chacune
{
    // faire quelque chose avec chaque exception
}

4voto

rory.ap Points 14298

Vous devez utiliser InnerException ou InnerExceptions, en fonction de votre situation:

if (x.InnerException is TaskCanceledException)
{
    // ...
}

Le code ci-dessus fonctionnera si vous savez que vous n'avez qu'une seule exception; cependant, si vous en avez plusieurs, alors vous voudrez faire quelque chose avec chacune d'elles:

var sb = new StringBuilder();

foreach (var inner in x.InnerExceptions)
{
    sb.AppendLine(inner.ToString());
}

System.Diagnostics.Debug.Print(sb.ToString());

0voto

Anton Sterr Points 28

Vérifier le type de l'InnerException a fonctionné :

        catch (AggregateException ae)
        {
            if (ae.InnerException is TaskCanceledException)
            {
                LoggerService.Log(LogLevel.Error, "La requête GetReport a été annulée");
                throw ae.InnerException;
            }

            LoggerService.Log(LogLevel.Error, string.Format("La requête GetReport a échoué : {0}", ae.InnerException.Message));
            throw;
        }

MAIS après que l'exception soit lancée sur la communication WCF, elle est à nouveau encapsulée dans une AggregateException. Et pour une raison quelconque, le mécanisme pour lire le deuxième type d'exception n'est pas si simple. Mais avec ce qui suit, cela fonctionne :

                catch (AggregateException ae)
                {
                    endMessage = string.Format("La requête définie a échoué. Erreur : {0}", ae.Message);

                    // Définir un message d'erreur spécifique lorsque TaskCanceledException est contenu dans AggregateException
                    var fe = ae.InnerException as FaultException;
                    if (fe != null) if (Type.GetType(fe.Detail.Type) == typeof(TaskCanceledException)) endMessage = "La requête définie a été annulée";

                    logLevel = LogLevel.Error;
                    messageType = MessageType.Error;
                }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X