IMHO, the correct answer to "How should I handle exceptions?" is "Do Not." ("Unless you know how to recover from a specific exception." (e.g. `FileNotFoundException`s are easy to deal with. However, if you try to handle things like `DivideByZeroException`, `OutOfMemoryException`, or `StackOverflowException`, you're pretty much attached by an inclined plane wrapped helically around an axis.) Also (I might catch (pun intended) a lot of flak for this): - re-throwing exceptions should be avoided like the plague, as doing so can potentially cause a single exception to be logged multiple times. Unfortunately, of the `async`/`await` (i.e. things in the `System.Threading.Tasks` namespace) re-throw a lot, which leads to a lot of noise and distractions while debugging). - a `catch { ... }` block is the wrong place to log exceptions. A better alternative is use [Exception Filters] for logging. For example:
try {
Foo();
}
catch(SpecificException ex) when (ex.Log()) {
}
(Where `.Log` is an extension method that always returns `false`). An even better alternative is to avoid logging exceptions in `catch` blocks or exception filters altogether. I am glad that it was decided not to remove the `System.AppDomain` class in .NET Core and .NET 5+ for this very reason: you can use the [AppDomain.FirstChanceException] and [AppDomain.UnhandledException] events as the one (erm... OK, two) place(s) to log all exceptions. You can even get fancy and add something to the `Exception.Data` dictionary in those events to avoid logging the same exception multiple times. However, in order for this to be useful, exceptions should not be re-thrown in order to ensure the logging of complete stack traces.
Eagles my fly, but weasels don't get sucked into jet engines.