Wednesday, July 2, 2008, 10:16 PM - Design concepts
This post was written keeping in mind the Exceptions in C++, but may equally apply to other languages.I have more than N times had the tough call to decide whether to throw an exception or to return an error from a new function that I write. Frankly speaking I have used the return statement more often than throwing an exception. Exception had always appeared an unnecessary overhead to me and appeared to make my code look less graceful.
However of late I have been working on developing a library where APIs are exposed for others to use. Throwing an exception has started making a lot of sense to me when I am developing a library for which I have no control on how my functions would be called. Even here I seem to often ask myself : Is throwing an exception the right thing or returning an error code the more right thing? Below are a list of guidelines that I try to follow to come to that decision:
Throw an exception knowing that if the caller does not catch it, the application will terminate. In other words, throw exceptions for grave errors. Returning an error code does not terminate the application if the caller does not handle it. In other words, use exceptions for critical errors that cannot be ignored. Use error codes if the error isn't severe and may be ignored. This fact is a good yardstick to decide if you want to return or to throw an exception.
If you have an error throw it, if you have a state, return it. But isn’t an error just another state? Yes and No. My take is that if you think that the caller has done a grave error against the functionality, throw an exception. As an example, the caller gave a corrupted .mp3 file to the function PlayMusic(char* file), I would throw an exception if I can detect the corruption. If I detect that I have no read permission of the file, I may return an error. If the file does not exists, it may do either of it. So it appears to me that we have to live in a mixed world and use what makes sense to us and what makes your code more graceful.
In constructors, exceptions are the only way to point a finger to the caller. You cannot return an error code from a constructor; you only have the option of throwing an exception. You can also use another member variable to indicate that the object is not properly initialized, but the later is just a workaround for not utilizing the power of the language.
If your function has the possibility to return more than one set of error values, use exceptions. In other words, if you really want the user of your function to debug what went wrong through an exception of a user-defined type, you should prefer exception over error codes. Even if you think that the caller cannot correct the reason for the exception, it not a reason for not throwing an exception.
If it makes sense make a single ApplicationException that can hold reasons for several exceptions rather than making a FooException, a DoException, a NoDataException, a InvalidDataExceptions, etc. Do this if it makes life easier and more sense to the user of your function and not to you. In other words, design exception classes on a subsystem by subsystem basis.
Though there are no hard rules, I have one to share: Don't treat exceptions as a glorified form of return statement and don’t use it for your fancy or to demonstrate your OO programming skills.
Don’t be carried away by those first paragraphs in books that tell you the advantages of using exceptions over if-then-else. They promise low bug-rate, improved product quality, less testing time, less maintenance cost. You may end up getting the exact opposite results if you don’t use your own judgment.
Tip:
Talking to somebody in your team who hates exceptions followed by somebody who love exceptions may help.
Links:
-- What should I throw?
-- What does Google's C++ style guide have to say about Exceptions?
Happy Throwing.//




( 0 / 0 )



Calendar




