JoshRivers
JoshRivers

Reputation: 10290

C# Can you examine an exception without catching?

I have some framework / AOP code that logs exceptions from methods called deeper inside...

try {
  ..invoke inner code...
}
catch (Exception e) {
  log(e);
  throw;
}

This works great except for one thing...when my team tries to debug their code in Studio, they only see the exception happening in the logging code (since it gets handled, and then thrown from there).

Is there any way I can get Studio to ignore that my code is catching/throwing an exception...or to inspect the exception on it's way through without catching it?

UPDATE: The issue is that I have framework code that prevents the correct break-point for the real exception from being hit. I am aware that the debugger in visual studio is capable of fine-grained configuration, and I am hoping that someone here can provide a higher level insight than "Learn VS2010 in 31 Hours" does. I simply want to BOTH log the exceptions that are caused in inner code, AND have the break happen at the site of the error WITHOUT turning on 'Break on All Exceptions' which would cause my team to spend 5 minutes pressing the 'Continue' button every time they launched the app (but that's another story).

UPDATE 2: The primary question here, is how can I log the exception, but have the debugger not stop on the 'throw' in my logger, but on the initial exception, without having the debugger stop on all exceptions thrown.

Upvotes: 2

Views: 1538

Answers (3)

supercat
supercat

Reputation: 81159

It is possible in VB.NET to examine an exception without catching it, and before any stack unwinding has occurred as a consequence of it. While it is generally dangerous to do very much between the time the exception has been thrown and the time the stack has been unwound, one may capture the exception and then make use of it in a finally block. One might also set a flag or other indicator to let stack-unwinding code know where the exception is going to be caught. Unfortunately, the usefulness of the latter ability is limited because of a (largely language-forced) anti-pattern of code catching exceptions that it needs to react to, but that can't expect to resolve. For example, if an exception is thrown in a constructor after it has created some IDisposable objects and stored them in fields, the constructor has to react to the exception by cleaning up the fields it has created, but has no hope of resolving the situation and returning normally. If a constructor might have multiple return points, it would be semantically cleaner of one could say:

try
{
  ... create IDisposables
}
finally(Exception ex)
{
  if (ex != null)
    this.Dispose();
}

than having to say

try
{
  ... create IDisposables
}
catch(Exception ex)
{
  this.Dispose();
  throw ex;
}

since the former would avoid catching an exception it had no expectation of handling. One could write a wrapper method in VB that would accept a pair of delegates and implement the second using the same semantics as the finally(Exception ex) above would have, but unfortunately C# provides no such facility itself.

Upvotes: 0

JoshRivers
JoshRivers

Reputation: 10290

I've done some digging, and the answer in 1349613 put me on a good scent. I've added the attribute:

[DebuggerNonUserCode]

To my logging class. Now when the internal, invoked code throws an exception, the debugger ignores the logging code, and it's Try/Catch block, and goes straight to the internal exception.

Upvotes: 1

Blindy
Blindy

Reputation: 67380

Actually you can make VS break on exceptions. Go to the Debug menu, click exceptions and check both the checkboxes for "Common Language Runtime Exceptions". Now you'll get a debug break at the point the exception is thrown.

Upvotes: 2

Related Questions