I have a method like:
public TResult DoSomethingWithLogging<TResult>(Func<TResult> someAction)
{
try
{
return someAction.Invoke();
}
catch (Exception ex)
{
LogException(ex)
throw;
}
This method is used as follows:
var result = DoSomethingWithLogging(() => Foo());
I also want to log exceptions that were caught inside Foo()
. I cannot use throw
in catch
inside of Foo
.
How can I catch such exceptions?
Example:
public static string Foo()
{
try
{
return "Foo";
}
catch (Exception)
{
// I have to log this exception too without adding anything to Foo
return "Exception caught";
}
}
You can bind to the FirstChanceException
event. Here's your code modified to demonstrate this:
using System;
using System.Runtime.ExceptionServices;
public class Program
{
public static void Main()
{
AppDomain.CurrentDomain.FirstChanceException +=
(object source, FirstChanceExceptionEventArgs e) =>
{
Console.WriteLine("FirstChanceException event raised in {0}: {1}",
AppDomain.CurrentDomain.FriendlyName, e.Exception.Message);
};
Console.WriteLine("Hello World");
Console.WriteLine(DoSomethingWithLogging(() => Foo()));
}
public static TResult DoSomethingWithLogging<TResult>(Func<TResult> someAction)
{
try
{
return someAction.Invoke();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw;
}
}
public static string Foo()
{
try
{
throw new Exception("This will be caught");
return"Foo";
}
catch (Exception) //I have to log this exception too without adding anything too Foo
{
return "Exception caught";
}
}
}
As a rule, I'd be very cautious of this in anything other than debugging scenarios. Once it's caught it shouldn't be considered an exception by code higher up. (Of course, catching it in the first place could have been a logical error, hence this indeed having some value in debugging scenarios).
There are also complications in multi-threaded cases. The code above demonstrates how FirstChanceException
works, but if you attached before the call and then detached after it would still be triggered by any exceptions on other threads. Filtering those out could be tricky. I'd probably start by considering looking at the call-stack, but I'm not sure that's the best way.
You can do so by handling the AppDomain.FirstChanceException
event:
Occurs when an exception is thrown in managed code, before the runtime searches the call stack for an exception handler in the application domain.
See Catching First Chance Exceptions in Managed Code without being debugged.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With