Je sais parfois que innerException est nul
Donc, les éléments suivants peuvent échouer:
repEvent.InnerException = ex.InnerException.Message;
Existe-t-il un moyen ternaire rapide de vérifier si innerException est nul ou non?
Est-ce ce que vous recherchez?
Ssortingng innerMessage = (ex.InnerException != null) ? ex.InnerException.Message : "";
De bonnes réponses jusqu’à présent. Sur une note similaire, mais différente, il existe parfois plusieurs niveaux d’exceptions nestedes. Si vous voulez obtenir l’exception racine qui a été lancée à l’origine, quelle que soit sa profondeur, essayez ceci:
public static class ExceptionExtensions { public static Exception GetOriginalException(this Exception ex) { if (ex.InnerException == null) return ex; return ex.InnerException.GetOriginalException(); } }
Et en cours d’utilisation:
repEvent.InnerException = ex.GetOriginalException();
C’est drôle, je ne trouve rien de mal avec Exception.GetBaseException () ?
repEvent.InnerException = ex.GetBaseException().Message;
La solution la plus simple consiste à utiliser une expression conditionnelle de base:
repEvent.InnerException = ex.InnerException == null ? null : ex.InnerException.Message;
Pourquoi tant de récursivité dans ces réponses?
public static class ExceptionExtensions { public static Exception GetOriginalException(this Exception ex) { while(ex.InnerException != null)ex = ex.InnerException; return ex; } }
Cela semble être un moyen beaucoup plus simple de le mettre en œuvre.
C’est une vieille question mais pour les futurs lecteurs:
En plus des réponses déjà postées, je pense que la méthode correcte (lorsque vous avez plusieurs InnerException) est la méthode Exception.GetBaseException.
Si vous voulez l’instance d’exception, procédez comme suit:
repEvent.InnerException = ex.GetBaseException();
Si vous recherchez uniquement le message de cette manière:
repEvent.InnerException = ex.GetBaseException().Message;
Avec C # 6.0, vous pouvez utiliser:
ssortingng message = exception.InnerException?.Message ?? ""
ssortingng message = exception.InnerException?.Message ?? ""
;
Cette ligne de code est similaire à:
ssortingng message = exception.InnerException == null ? "" : exception.InnerException.Message
ssortingng message = exception.InnerException == null ? "" : exception.InnerException.Message
.
Parfois aussi InnerException a une InnerException, vous pouvez donc utiliser une fonction récursive pour cela:
public ssortingng GetInnerException(Exception ex) { if (ex.InnerException != null) { return ssortingng.Format("{0} > {1} ", ex.InnerException.Message, GetInnerException(ex.InnerException)); } return ssortingng.Empty; }
Avec C # 6.0, vous pouvez le faire en une seule ligne.
repEvent.InnerException = ex.InnerException?.Message;
pour d’autres fonctionnalités de C # 6.0, cliquez ici
Oui:
if (ex.InnerException == null) { // then it's null }
Voici une autre implémentation possible qui ajoute les messages et les traces de stack pour que nous les remplissions complètement:
private static Tuple GetFullExceptionMessageAndStackTrace(Exception exception) { if (exception.InnerException == null) { if (exception.GetType() != typeof(ArgumentException)) { return new Tuple(exception.Message, exception.StackTrace); } ssortingng argumentName = ((ArgumentException)exception).ParamName; return new Tuple(Ssortingng.Format("{0} With null argument named '{1}'.", exception.Message, argumentName ), exception.StackTrace); } Tuple innerExceptionInfo = GetFullExceptionMessageAndStackTrace(exception.InnerException); return new Tuple( Ssortingng.Format("{0}{1}{2}", innerExceptionInfo.Item1, Environment.NewLine, exception.Message), Ssortingng.Format("{0}{1}{2}", innerExceptionInfo.Item2, Environment.NewLine, exception.StackTrace)); } [Fact] public void RecursiveExtractingOfExceptionInformationOk() { // Arrange Exception executionException = null; var iExLevelTwo = new NullReferenceException("The test parameter is null"); var iExLevelOne = new ArgumentException("Some test meesage", "mySsortingngParamName", iExLevelTwo); var ex = new Exception("Some higher level message",iExLevelOne); // Act var exMsgAndStackTrace = new Tuple("none","none"); try { exMsgAndStackTrace = GetFullExceptionMessageAndStackTrace(ex); } catch (Exception exception) { executionException = exception; } // Assert Assert.Null(executionException); Assert.True(exMsgAndStackTrace.Item1.Contains("The test parameter is null")); Assert.True(exMsgAndStackTrace.Item1.Contains("Some test meesage")); Assert.True(exMsgAndStackTrace.Item1.Contains("Some higher level message")); Assert.True(exMsgAndStackTrace.Item1.Contains("mySsortingngParamName")); Assert.True(!ssortingng.IsNullOrEmpty(exMsgAndStackTrace.Item2)); Console.WriteLine(exMsgAndStackTrace.Item1); Console.WriteLine(exMsgAndStackTrace.Item2); }
class MyException : Exception { private const ssortingng AMP = "\r\nInnerException: "; public override ssortingng Message { get { return this.InnerException != null ? base.Message + AMP + this.InnerException.Message : base.Message; } } public override ssortingng StackTrace { get { return this.InnerException != null ? base.StackTrace + AMP + this.InnerException.StackTrace : base.StackTrace; } } }
Avec ce code, vous serez sûr de ne perdre aucun message d’exception interne
catch (Exception exception) { Logger.Error(exception.Message); while (exception.InnerException != null) { exception = exception.InnerException; Logger.Error(exception); } }
Il est possible d’utiliser un filtre d’exception pour obtenir une visée plus précise.
catch (Exception ex) when (ex.InnerException != null) {...}
S’il vous plaît trouver plus de détails ici