How can we easily find what line in the code causes a runtime exception?

c#, roslyn

Solution

So you should have still gotten a break in, but if you didn't a few things to check:

Go under the Debug menu, and choose Exceptions. You'll see a column for "Thrown" or "User-unhandled". Either find NullReferenceException with Find, and check a checkbox for "thrown". That'll cause VS to break as soon as a NullReferenceException is thrown. If you want to be really aggressive, you can tell it to break on all exceptions.

If that's still not working, go under Tools > Options, Debugging, General and clear "just my code". The caveat here is this will break on all exceptions, including ones in parts of VS that aren't even your fault. (Sadly, we throw lots of exceptions in lots of various places.)

If you want, feel free to file a bug so we can make our message include the stack trace and line/column so it's easier to debug.

And since I'm here: your code did

var isCorrectTypeOfExpression = (obj.Type as IdentifierNameSyntax).Identifier.Text == typeof(ArgumentException).Name;

Be careful with the syntax checks -- what happens if I write `throw new System.ArgumentException()`? The proper approach is to get the semantic model and bind the ObjectCreationExpression to figure out what the real type is. (It'll also mean you work in the case of aliases, if you care.)

Problem

Consider the following analyzer: ``` public void AnalyzeNode(SyntaxNode node, SemanticModel semanticModel, Action<Diagnostic> addDiagnostic, CancellationToken cancellationToken) { var throwStatement = node as ThrowStatementSyntax; var isObjectCreationExpression = throwStatement.Expression is ObjectCreationExpressionSyntax; var obj = throwStatement.Expression as ObjectCreationExpressionSyntax; var isCorrectTypeOfExpression = (obj.Type as IdentifierNameSyntax).Identifier.Text == typeof(ArgumentException).Name; } ``` With `SyntaxKind.ThrowStatement` as the Kind of Interest. `obj` should be `null` if the thrown exception has not been declared right there in the form `new Exception()` but is rather presented as `throw e` where `e` is a previously declared exception. This in turn will throw a `NullReferenceException` when `obj.Type` is called right after. Example in question: ``` static void Method1() { throw new ArgumentException(); } static void Method2(ArgumentException e) { throw e; } ``` The first `throw` will pass the analyzer just fine, but the second one will cause `obj` to be `null` since it is not of type `ObjectCreationExpressionSyntax`. In the sandbox Visual Studio environment this will show up as an information message: The User Diagnostic Analyzer 'FormattingFixes.EmptyArgumentException.ArgumentExceptionAnalyzer' threw an exception with message 'Object reference not set to an instance of an object.'. In this short sample it's easy to tell where the problem is, but in a less contrived example it will be harder to spot. The line and column are both `1`, not helpful. In "traditional" programming, your environment automatically shows you where the runtime exception was thrown and what the values are at that point in time. I can put a random breakpoint somewhere in my code, look at all values every time it's hit and try to deduce it from there, but this doesn't scale well once the amount of nodes goes much higher than these 2. How can we easily find what line in the code causes a runtime exception?

Original source