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 Bug in System.Random constructor? and 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?
It depends. TryParseFoo
should catch all parsing exceptions for stuff like null or misformatted strings. But there are also unrelated exceptions (ThreadAbortException
, say) that should not be automatically quieted.
In Python (bear with me), you can cause a lot of trouble by catching KeyboardInterrupt
exceptions, which basically means your program keeps running even if you Ctrl-C out of it.
My rule of thumb is that you should use TryFoo
when you want to Foo
without cleaning up your inputs. If TryFoo
catches errors unrelated to Foo
ing your input, it's being too aggressive.
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