Nicholas Blumhardt wrote about implementing the Specification Pattern using Linq. And Rinat Abdullin did something similar using XPO. These are both very neat approaches. But there is something I was wondering about…
Exceptions.
Both approaches pass around an instances of IQueryable<>. In the Linq to SQL world, IQueryable<> will be turned into a SQL query and then executed against the database. And it will be done with extension methods like Count, ToArray, ToList, etc. are called. It is a neat system. But what about exceptions? If I pass out an IQueryable<> instance that is implemented by a database provider (ADO.NET, NHibernate, etc.), I have to know that so that I can catch the correct exception.
Now it is well know in the Java world that the Hibernate (and probably the NHibernate) guys don’t think you should wrap exceptions. Just let it go and deal with the technology specific exception. I understand the hibernate position. They are the abstraction over your database. No reason to have an abstraction over an abstraction.
But a few things I’ve read in the DDD/TDD/<whatever>DD world are to have these repository abstractions so you can change it to be file system backed, DB backed, etc. All worthy(?) goals, but when you start passing around things that allow the abstraction to leak…
Fail Fast -
There are those out there that will say “Why are you catching those exceptions? Just let them crash your app. It is the fail fast approach”. Poppycock! For example, if you try to connect to a SQL server and it is down, why can’t the app go into a wait state until it can connect again? The app should definitely alarm and let someone know. But in the majority of cases, it is because a patch was applied to the DB server, the DB was rebooted, and the connections need to be re-established. Those are the types of things that code is good at handling. I know this is one example. And a simple one at that. But the premise stands.
I guess the few years I spent at Amazon gave me an appreciation for self correcting code. No amount of coding can bring something back from the “dead”. But I do have a new way of defining “dead”.
I know. I’m a killjoy. Ask anyone on my team :) I spend more time worrying about the error handling, monitoring, and overall health code than anything else in the system. Solving the business problem is only 40% of the job in my mind. Writing code to figure out what went wrong is 40%. And telling people what it is wrong and what possible solutions might be is 20%.
Oh yeah…a big round of thanks to Nicholas and Rinat for working on my favorite IoC container - Autofac.



