Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't C# have support for first pass exception filtering?

Note: this is not a duplicate of Jeff's question.

That question asked "Is an equivalent?" I know there isn't, and I want to know why!

The reason I ask is that I've only just become clear on how important it is, and the conclusion seems very strange to me.

The Exception Handling block of Microsoft's Enterprise Library advises us to use this pattern:

catch (Exception x) {     if (ExceptionPolicy.HandleException(x, ExceptionPolicies.MyPolicy))         throw;      // recover from x somehow } 

The policy is defined in an XML file, so that means that if a customer has an issue, we can modify the policy to assist with tracking down (or perhaps papering over) the problem to give them a fast resolution until we deal with it properly - which may involve arguing with 3rd parties, about whose fault it all is.

This is basically an acknowledgement of the simple fact that in real applications the number of exception types and their "recoverability" status is practically impossible to manage without a facility like this.

Meanwhile, the CLR team at MS says this is not an option, and it turns out those guys know what they're talking about! The problem is that right before the catch block runs, any finally blocks nested inside the try block will be executed. So those finally blocks may do any of the following:

  • Harmlessly modify the program state (phew, lucky).
  • Trash something important in the customer's data, because the program state is screwed up to an unknown degree.
  • Disguise or destroy important evidence that we need to diagnose an issue - especially if we're talking about calls into native code.
  • Throw another exception, adding to the general confusion and misery.

Note that the using statement and C++/CLI destructors are built on try/finally, so they're affected too.

So clearly the catch/throw pattern for filtering exceptions is no good. What is actually needed is a way to filter exceptions, via a policy, without actually catching them and so triggering the execution of finally blocks, unless we find a policy that tells us the exception is safe to recover from.

The CLR team blogged about this recently:

  • Catch, Rethrow and Filters - Why should you care?
  • Why catch(Exception)/empty catch is bad

The outcome is that we have to write a helper function in VB.NET to allow us to access this vital capability from C#. The big clue that there is a problem is that there is code in the BCL that does this. Lots of people have blogged about doing it, but they rarely if ever mention the thing about try/finally blocks, which is the killer.

What I would like to know is:

  • Are there any public statements or direct emails people have received from the C# team on this subject?
  • Are there any existing Microsoft Connect suggestions asking for this? I've heard rumours of them but none of the likely keywords turned up anything.

Update: as noted above, I have already searched on Microsoft Connect without finding anything. I have also (unsurprisingly) Googled. I've only found people explaining why they need this feature, or pointing out the advantages of it in VB.NET, or fruitlessly hoping that it will be added in a future version of C#, or working around it, And plenty of misleading advice. But no statement on the rationale for omitting it from all current versions of C#. And the reason I'm asking about existing Connect issues is so that (a) I don't create an unnecessary duplicate and (b) I can tell interested people if I have to create one.

Update 2: Found an interesting old blog post from Eric Gunnerson, formerly of the C# team:

"Yes, being able to put a condition on a catch is somewhat more convenient than having to write the test yourself, but it doesn't really enable you to do anything new."

That was the same assumption I had until it was properly explained to me!

like image 257
Daniel Earwicker Avatar asked Mar 02 '09 12:03

Daniel Earwicker


People also ask

Why there is no string in C?

There is no string type in C . You have to use char arrays. By the way your code will not work ,because the size of the array should allow for the whole array to fit in plus one additional zero terminating character.

Why C has no exception handling?

As such, C programming does not provide direct support for error handling but being a system programming language, it provides you access at lower level in the form of return values. Most of the C or even Unix function calls return -1 or NULL in case of any error and set an error code errno.

Why array bounds checking is not available in C?

This is due to the fact that C++ does not do bounds checking. Languages like Java and python have bounds checking so if you try to access an out of bounds element, they throw an error. C++ design principle was that it shouldn't be slower than the equivalent C code, and C doesn't do array bounds checking.

Why does C still exist?

The C programming language doesn't seem to have an expiration date. It's closeness to the hardware, great portability and deterministic usage of resources makes it ideal for low level development for such things as operating system kernels and embedded software.


1 Answers

As to any existing connect bugs. The following issue deals with exception fliters. The user did not explicitly state they wanted them be an actual filter in the sense of when they execute but IMHO it's implied by the logic.

https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=401668

Besides that issue though, there are no issues I can find or know of that are related to what you are looking for. I think it would do good to have a separate issue which explicitly calls out the want for VB.Net style exception filters.

I wouldn't worry too much about introducing a duplicate question if you've done a bit of due diligence looking for an existing one. If there is a dupe, Mads will dupe it accordingly and link you to the main request.

As for the part of getting an official response from the C# team, you will likely get that when you either 1) file a connect bug or 2) get duped against the main bug. I really doubt there is an official reason / justification out there right now.

Here's my speculation on the issue: My guess is that this feature simply wasn't on the original C# 1.0 feature set and since that time there hasn't been enough demand to make it into the language. The C# and VB team spend an unbelievable amount of time ranking language features at the start of every ship cycle. We have to make some very difficult cuts at times. Without sufficient demand there is very little chance a feature will make it into the language.

Up until recently I bet you would be hard pressed to find 1 out of 10 people who understood the difference between VB.Net's Try/When and just using a plain old if statement in a C# catch block. It seems to be a bit more on peoples minds lately so maybe it will make it into a future version of the langauge.

like image 185
JaredPar Avatar answered Sep 24 '22 02:09

JaredPar