Short story about exception filters: they're mostly there for crash dumps.
The background is that there is a piece of functionality in Windows previously called Watson, now called Windows Error Reporting. It's that dialog that pops up when an application crashes that asks if you'd like to report the crash to Microsoft. If you do, it sends a crash dump to Microsoft, where it can then be routed to the owner of the application, even if the application isn't actually developed by Microsoft.
So a lot of developers in the know have designed their applications so that unrecoverable errors actually purposely cause the application to crash so that they can get a dump from WER. One of the standard ways of doing this is simply wrapping your code in a catch at the top level and then calling Environment.FailFast to crash the process.
The problem is that sometimes the stack is destroyed in this process. Note that I didn't say the stack trace -- the stack is destroyed. You can see this if you catch and rethrow an exception. The locals from the original exception are gone, so now the dump is far more difficult to debug.
Exception filters let you get around this because they don't actually pop anything, including the exception, from the stack, so if you FailFast, you crash with the full stack of the process.
A number of .NET developers had previously figured this out and were doing a bunch of nasty stuff to get this behavior, like including a VB net module with an exception filter fail-fast, or ildasm/ilasming their assembly. We tried a bunch of these methods on the compiler and they were all a source of many really obnoxious bugs, so eventually another compiler developer and I just said "screw it" and implemented exception filters in C#. All the bugs went away and we lived happily ever after.
Oh, and now exception filters are in the language.
Main purpose of this mechanism is ability to not catch some exceptions at all so that full state of memory (primarily stack itself) is preserved in crash dump or for inspection in attached debugger (which seems like more useful case to me).
With that purpose in mind, wrapping your application on the top level with try ... catch (Exception) {abort()} negates any benefit that you may get out of exception filters.
The finally clause does not have access to the exception details, as it executes regardless of whether there is an exception or not. You can't do "Log(ex);" in the finally block. And you would want to put the exception into the log.
You also need a boolean and a few extra lines of control code as your example shows.
So basically, the CLR has ugly behavior on rethrows that can only be sanely described as a bug but it's a common-law feature at this point so we're using an ugly linguistic construct to work around it.
I know CLR already supports exception filters - I've used VB.Net. You miss my point - the whole point of exception filters is to work around the way that the rethrow operation (that is, the naked "throw" without any given exception within a catch clause, so it pulls the contextual exception) screws up your stack-trace.
Rethrowing an exception should not screw up the stack-trace. But they do, so we need to use the irritating exception filter mechanic.
Separate exception catching from stack unwinding as in the Lisp condition system, where low-level code decides when to call high-level code and what options to present it, and the high-level code does whatever it wants to do and then picks an option.
That more or less gives you what Microsoft calls 'edit and continue' in every program, where your high-level code decides what code does the edit and decides on how to continue.
There's an option for that in Visual Studio. It's not enabled by default, but I've found it handy for situations like this.
The other alternative is what C# 6 added: eliminating the need to rethrow in as many circumstances in the first place, so 'logically' unhandled exceptions can be actually unhandled.
Often the only difference between encoding the type in a string, and encoding the type in a full-blown typed Exception is perhaps 'Find All References'. Typing the Exception can be a waste of typing and unnecessary cruft. More "structure" is not always better.
If there's some unique data which must be carried back up the stack with the Exception it's a different story.
In C#, throw also re-throws and preserves the stack trace in the exception object. What the article points out that it doesn't do is preserve the full call stack and method state in the Visual Studio debugger, and that only if you explicitly turn off break on throw, leaving it in break on throwing uncaught exceptions instead.
In fact, changing state in an exception filter method that always returns false sounds terrible to me. What if you actually need to do something with that exception, or to clean up state? What if the Log method does something wrong that you need to debug? Exception filters are handy, but I hope to never see them used like that.
Now the new null propagation operator, on the other hand, get me some of that, and I hope to see it used everywhere.
Doesn't look great. It's not easy to understand what this code does. I'd better rewrite it this way:
catch if(IsExceptionLogged())
So we can see here "Is" keyword, it gives us a hint that this function returns boolean. We can see the main operation, and it's more human-readable. And we can easily understand what do we mean here. Because in case of Log() we have to think - should we catch if it was logged or if it was not logged.
Maybe it is useful in some cases. But unfortunately the code quality doesn't depend on the tools one uses, and it's nothing about language features. 99% of developers don't know how to use C# 1.0. There are so still a lot for them to learn.
Maybe even
catch if(IsExceptionHandled())
is better. Because I don't see any reasons why should we catch exceptions if it was logged. Yep, it was logged - is it a good decision factor to catch? Logging often can be disabled in configuration.
Calling the Log function there is a hack to work around the stack being unwound inside catch blocks, it isn't being used to control whether the catch block is run based on whether logging is turned on or not, so those suggested alternative names seem confusing.
"IsExceptionLogged" implies that the function is being called for its return value, to work out whether the exception is being looked or not, but in this usecase the Log function is being called for its side affects, and the return value is a boolean simply to appease the type checker.
PS It's also a bad idea to compare exception messages. Well, I know, it's a sample, but just wanna point that it's not the best one. First - exception messages could be internationalized. Second - general string comparison should be done with InvariantCulture, and case-ignorant (and usually strings are trimmed). And even in that case it's not a good idea. It's better to compare types, or message codes.
The background is that there is a piece of functionality in Windows previously called Watson, now called Windows Error Reporting. It's that dialog that pops up when an application crashes that asks if you'd like to report the crash to Microsoft. If you do, it sends a crash dump to Microsoft, where it can then be routed to the owner of the application, even if the application isn't actually developed by Microsoft.
So a lot of developers in the know have designed their applications so that unrecoverable errors actually purposely cause the application to crash so that they can get a dump from WER. One of the standard ways of doing this is simply wrapping your code in a catch at the top level and then calling Environment.FailFast to crash the process.
The problem is that sometimes the stack is destroyed in this process. Note that I didn't say the stack trace -- the stack is destroyed. You can see this if you catch and rethrow an exception. The locals from the original exception are gone, so now the dump is far more difficult to debug.
Exception filters let you get around this because they don't actually pop anything, including the exception, from the stack, so if you FailFast, you crash with the full stack of the process.
A number of .NET developers had previously figured this out and were doing a bunch of nasty stuff to get this behavior, like including a VB net module with an exception filter fail-fast, or ildasm/ilasming their assembly. We tried a bunch of these methods on the compiler and they were all a source of many really obnoxious bugs, so eventually another compiler developer and I just said "screw it" and implemented exception filters in C#. All the bugs went away and we lived happily ever after.
Oh, and now exception filters are in the language.