Skip to content

ArgumentNullException for exception re-throw in switch in try-catch #55

@metakirby5

Description

@metakirby5

The issue occurs on version 0.4.0 from NuGet, in Unity 2022.3.50f1.

(Using 0.5.0 created a lot of errors that proved even more difficult to diagnose, and I figured it was due to supported .NET/C# versions.)

I found this issue when integrating the analyzer with our project, and found a specific repro:

      try { } catch (Exception e) {
        switch (e) {
          default:
            throw;
        }
      }

This creates the following compilation error:

SyntaxNode: switch (e) { default: throw; } [SwitchStatementSyntax]@[5148..5208) (159,8)-(162,9)
System.Exception: Uncaught exception in analyzer: System.ArgumentNullException: Value cannot be null. (Parameter 'syntax')    at Microsoft.CodeAnalysis.CSharp.CSharpSemanticModel.CheckSyntaxNode(CSharpSyntaxNode syntax)    at Microsoft.CodeAnalysis.CSharp.CSharpSemanticModel.GetTypeInfo(ExpressionSyntax expression, CancellationToken cancellationToken)    at Microsoft.CodeAnalysis.CSharp.CSharpExtensions.GetTypeInfo(SemanticModel semanticModel, ExpressionSyntax expression, CancellationToken cancellationToken)    at ExhaustiveMatching.Analyzer.SwitchStatementAnalyzer.IsExhaustive(SyntaxNodeAnalysisContext context, SwitchStatementSyntax switchStatement)    at ExhaustiveMatching.Analyzer.SwitchStatementAnalyzer.Analyze(SyntaxNodeAnalysisContext context, SwitchStatementSyntax switchStatement)    at ExhaustiveMatching.Analyzer.ExhaustiveMatchAnalyzer.AnalyzeSwitchStatement(SyntaxNodeAnalysisContext context)
   at ExhaustiveMatching.Analyzer.ExhaustiveMatchAnalyzer.AnalyzeSwitchStatement(SyntaxNodeAnalysisContext context)
   at Microsoft.CodeAnalysis.Diagnostics.AnalyzerExecutor.<>c__62`1.<ExecuteSyntaxNodeAction>b__62_0(ValueTuple`2 data)
   at Microsoft.CodeAnalysis.Diagnostics.AnalyzerExecutor.ExecuteAndCatchIfThrows_NoLock[TArg](DiagnosticAnalyzer analyzer, Action`1 analyze, TArg argument, Nullable`1 info)

It can be "fixed" by throwing the exception again instead of re-throwing, but doing so would get rid of the stack trace.

      try { } catch (Exception e) {
        switch (e) {
          default:
            throw e; // instead of rethrow
        }
      }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions