I was recently told that I’m abusing exceptions to control the flow in my applications, so I this is my attempt to somehow clarify the situation.
To my mind, a method should throw an exception, when it encounters a situation, which can’t be handled internally or might be handled better by the calling side.
So – does any particular set of rules exist, which can be used to answer the following set of question when developing your applications:
-
When should I throw an exception and when should I write code with strong nothrow guarantee, which might simply return
boolto indicate success or failure? -
Should I try to minimize the number of situations, when the method throws an exception or , on the contrary, should it be maximized to provide flexibility when handling these situations?
-
Should I stick to the exception throwing convention set by the frameworks / runtimes I use when developing my applications or should I wrap all these calls so that they match my own exception throwing strategy?
-
I was also adviced to use error codes for error handling, which seems pretty efficient, but ugly from the syntactical point of view (also, when using them a developer loses the ability to specify the output for a method). What do you think about this?
Example for the third question (I was using an I/O framework and encountered the following situation):
The described framework does not use exceptions to handle errors, but
the other code does use them. Should I wrap every possible failure
indicated with'???'and throw an exception in this case?
Or should I change the signature of my method tobooland only indicate whether the operation was
PrepareTheResultingOutputPath
successful or not?
public void PrepareTheResultingOutputFile(
String templateFilePath, String outputFilePath)
{
if (!File.Exists(templateFilePath))
// ???
if (!Directory.MakePath(outputFilePath))
// ???
if (File.Exists(outputFilePath))
if (!File.Remove(outputFilePath))
// ???
if (!File.Copy(templateFilePath, outputFilePath)
// ???
}
Another example – even the .NET Framework doesn’t follow some strict exception throwing strategy. Some methods are documented to throw 10+ different exception types, including trivial exception types like NullArgumentException, but some of them simply return bool to indicate success or failure of the operations.
Thank you!
The problem with exceptions is that they are essentially glorified gotos that have the ability to unwind the program’s call stack. So, if you are “using exceptions for flow control,” you are probably using them as gotos rather than as indications of an exceptions condition. That’s exactly the point of exceptions, and the reason for their name: they are supposed to be used only in exceptional cases. So, unless a method is designed not to throw an exception (an example is .NET’s
int.TryParse), it’s OK to throw an exception in response to exceptional circumstances.The nice thing about C# as opposed to Java is that in C# you can essentially return two or more values, by returning a tuple type or by using out parameters. So, there isn’t much ugliness in returning an error code as the method’s main return value, since you can use out parameters for the rest. For example, the common paradigm for calling
int.TryParseisNow for your third question, which seems to be the most substantial. In reference to your example code, you ask if you should return
boolto indicate success/failure or if you should use exceptions to indicate failure. There is a third option, though. You can define an enum to tell how the method could fail, and return a value of that type to the caller. Then, the caller has a wide choice: the caller doesn’t have to use a bunch of try/catch statements, or an if that gives little insight into how the method failed, but can choose to write eitheror
You can find more on this issue here and here, but especially in Joel Spolsky’s post, which I highly recommend.