I always felt that expecting exceptions to be thrown on a regular basis and using them as flow logic was a bad thing. Exceptions feel like they should be, well, the "exception". If you're expecting and planning for an exception, that would seem to indicate that your code should be refactored, at least in .NET...
However. A recent scenario gave me pause. I posted this on msdn a while ago, but I'd like to generate more discussion about it and this is the perfect place!
So, say you've got a database table which has a foreign key for several other tables (in the case that originally prompted the debate, there were 4 foreign keys pointing to it). You want to allow the user to delete, but only if there are NO foreign key references; you DON'T want to cascade delete.
I normally just do a check to see if there are any references, and if there are, I inform the user instead of doing the delete. It's very easy and relaxing to write that in LINQ as related tables are members on the object, so Section.Projects and Section.Categories and et cetera is nice to type with intellisense and all...
But the fact is that LINQ then has to hit potentially all 4 tables to see if there are any result rows pointing to that record, and hitting the database is obviously always a relatively expensive operation.
The lead on this project asked me to change it to just catch a SqlException with a code of 547 (foreign key constraint) and deal with it that way.
I was...
resistant.
But in this case, it's probably a lot more efficient to swallow the exception-related overhead than to swallow the 4 table hits... Especially since we have to do the check in every case, but we're spared the exception in the case when there are no children...
Plus the database really should be the one responsible for handling referential integrity, that's its job and it does it well...
So they won and I changed it.
On some level it still feels wrong to me though.
What do you guys think about expecting and intentionally handling exceptions? Is it okay when it looks like it'll be more efficient than checking beforehand? Is it more confusing to the next developer looking at your code, or less confusing? Is it safer, since the database might know about new foreign key constraints that the developer might not think to add a check for? Or is it a matter of perspective on what exactly you think best practice is?
Your lead is absolutely right. Exceptions are not just for once in a blue moon situations, but specifically for reporting other than expected outcomes.
In this case the foreign key check would still take place, and exceptions are the mechanism by which you can be notified.
What you should NOT do is catch and suppress exceptions with a blanket catchall statement. Doing fine-grained exception handling is specifically why exceptions were designed in the first place.
Wow,
First off, can you please distill the question down a bit, while it was nice to read a well thought out and explained question, that was quite a lot to digest.
The short answer is "yes", but it can depend.
File.Exists
boo-boo).In my opinion:
I would do both. If I can fail fast and provide a better user experience, great. Any expected SQL (or any other) exceptions should be getting caught and fed back appropriately anyway.
I know there is a concensus that exceptions should not be used for other than exceptional circumstances, but remember, we are crossing application boundaries here, expect nothing. Like I said, this is like the File.Exists
, there is no point, it can be deleted before you access it anyway.
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