A common pattern in the .NET Framework is the TryXXX pattern (I don't know if that's what they really call it), in which the called method attempts to do something, returning True
if it was successful, or False
if the operation failed. A good example is the generic Dictionary.TryGetValue
method.
Documentation for these methods say that they will not throw exceptions: that failure will be reported in the method return value. All good so far.
I recently encountered two different circumstances in which .NET Framework methods that implement the TryXXX pattern threw exceptions. See http://stackoverflow.com/questions/1148278/bug-in-system-random-constructor and http://stackoverflow.com/questions/1120283/uri-trycreate-throws-uriformatexception for details.
In both cases, the TryXXX
method called other methods that threw unexpected exceptions, and those exceptions escaped. My question: does this break the implied contract of not throwing exceptions?
Put another way, if you were writing TryFoo
, would you guarantee that exceptions cannot escape, by writing it like this?
public bool TryFoo(string param, out FooThing foo)
{
try
{
// do whatever
return true;
}
catch
{
foo = null;
return false;
}
}
It's tempting, because that guarantees no exceptions will escape, thereby honoring the implied contract. But it's a bug hider.
My gut feeling, based on my experience, says that this is a really bad idea. But if TryFoo
lets some exceptions escape, then what it's really saying is, "I won't throw any exceptions that I know how to handle," and then the whole idea of the contract "I won't throw exceptions" is thrown out the window.
So, what's your opinion? Should TryFoo
handle all exceptions, or just those that it's expecting to happen? What's your reasoning?