-
Exceptions vs. Return Values
I'm implementing someone else's design. The designer chose to use int return
values to indicate success/failure on methods. I mentioned that with .NET
it might make more sense to use exceptions. The designer agreed until he
read this paragraph from the MSDN article "Exception Management in .NET"
by Kenny Jones and Edward Jezierski.
"You should only throw exceptions when a condition outside of your code's
assumptions occurs. In other words, you should not use exceptions as a means
to provide your intended functionality. For example, a user might enter an
invalid user name or password while logging onto an application. While this
is not a successful logon, it should be a valid and expected result, and
therefore should not throw an exception. However, an exception should be
generated if an unexpected condition occurs, such as an unavailable user
database. Throwing exceptions is more expensive than simply returning a result
to a caller. Therefore they should not be used to control the normal flow
of execution through your code. In addition, excessive use of exceptions
can create unreadable and unmanageable code."
This parapraph implied to the designer that he really should still have a
return value to handle "normal" cases to indicate success/failure.
I don't disagree with the paragraph in the article, but with the interpretation
of the designer I'm working with. Now I'll have methods that throw exceptions
AND return success/failure which I think will confuse the developers who
are trying to use my methods. It means they will still have to check return
values after every method call, defeating the whole point of having exceptions.
If I'm forced to implement this design, it makes more sense to me to catch
all exceptions in my code with a generic exception handler and then in the
catch block just return 0. That way I'm at least consistent.
Any thoughts?
Here is the specific scenario if it help.
We will have a central app that other apps have to register with by using
remoting and calling a Register method. Periodically the apps need to CheckIn
otherwise they will be marked as being off line. Both of these methods have
return values of int to signify if the call was successful. Does this make
sense? To me it seems a perfect example of when to use exceptions. Then
the client app can make the method call and assume everything is fine unless
an exception is caught.
Michael
-
Re: Exceptions vs. Return Values
Hi Michael,
In all honesty, the paragraph you described can be interpreted in different
ways. Exceptions are a really good way to organize what went wrong. That
being said, it is *better* to not depend on exceptions for functionality.
However, this typically means that *client* side code shouldn't be written
sloppy and protected by wrapping exception handling around it.
For example, it is *better* that you code the following when you know it's
possible that you have a null reference:
If Not X Is Nothing Then
X.DoSomething()
End If
than it is to be lazy and fall back on generic exception handling:
Try
X.DoSomething()
Catch e As Exception
MsgBox("Something went wrong: " + e.ToString())
End Try
Also, exception handling (the Try block) should not be used to generically
replace branching (control flow - If, Select, etc.). These are examples of
bad things to do with exception handling.
As for the example you cited, a Login function either works or doesn't (authenticates
or not), and the return value might very well be a boolean. There's no real
need to return an "Invalid account or password" exception. However, should
anything else go wrong, such as you can't open the authentication source
(ADSI, database, etc.), then you should throw an exception.
In either case, you shouldn't return error codes AND throw exceptions - for
the *same* problems. That's just redundant, confusing, and won't work to
begin with.
The other thing to consider is that sometimes you need richer information.
Sometimes an error code number by itself doesn't help resolve or adequately
describe the problem. In this case, exceptions are certainly better. Also
consider balancing that against performance penalties. My tests show that
exception handling is only a problem when you depend on it, and it fires
often, in a tight loop. Otherwise, you can't really tell the difference.
-Rob
"Michael Welch" <billshewman@hotmail.com> wrote:
>
>I'm implementing someone else's design. The designer chose to use int return
>values to indicate success/failure on methods. I mentioned that with .NET
>it might make more sense to use exceptions. The designer agreed until he
>read this paragraph from the MSDN article "Exception Management in .NET"
>by Kenny Jones and Edward Jezierski.
>
>"You should only throw exceptions when a condition outside of your code's
>assumptions occurs. In other words, you should not use exceptions as a means
>to provide your intended functionality. For example, a user might enter
an
>invalid user name or password while logging onto an application. While this
>is not a successful logon, it should be a valid and expected result, and
>therefore should not throw an exception. However, an exception should be
>generated if an unexpected condition occurs, such as an unavailable user
>database. Throwing exceptions is more expensive than simply returning a
result
>to a caller. Therefore they should not be used to control the normal flow
>of execution through your code. In addition, excessive use of exceptions
>can create unreadable and unmanageable code."
>
>This parapraph implied to the designer that he really should still have
a
>return value to handle "normal" cases to indicate success/failure.
>
>I don't disagree with the paragraph in the article, but with the interpretation
>of the designer I'm working with. Now I'll have methods that throw exceptions
>AND return success/failure which I think will confuse the developers who
>are trying to use my methods. It means they will still have to check return
>values after every method call, defeating the whole point of having exceptions.
>
>If I'm forced to implement this design, it makes more sense to me to catch
>all exceptions in my code with a generic exception handler and then in the
>catch block just return 0. That way I'm at least consistent.
>
>Any thoughts?
>
>Here is the specific scenario if it help.
>
>We will have a central app that other apps have to register with by using
>remoting and calling a Register method. Periodically the apps need to CheckIn
>otherwise they will be marked as being off line. Both of these methods
have
>return values of int to signify if the call was successful. Does this make
>sense? To me it seems a perfect example of when to use exceptions. Then
>the client app can make the method call and assume everything is fine unless
>an exception is caught.
>
>Michael
>
>
-
Re: Exceptions vs. Return Values
Rob,
Thanks for your quick reply. I think I'm in agreement with what you say.
>
>In all honesty, the paragraph you described can be interpreted in different
>ways.
Yeah, don't I know it.
>
>As for the example you cited, a Login function either works or doesn't (authenticates
>or not), and the return value might very well be a boolean. There's no real
>need to return an "Invalid account or password" exception. However, should
>anything else go wrong, such as you can't open the authentication source
>(ADSI, database, etc.), then you should throw an exception.
>
The Login example is probably closest to my Register and CheckIn methods.
I guess I could see them returning ints (or booleans) for one particular
reason or set of reasons: input parameters were null or out of range. And
then throw exceptions for every other case. That would seem to take some
of the ambiguity out of it. However, I really can't foresee any reason for
the client of my method to pass in null arguments and would rather follow
the pattern of the collections in .NET and throw an ArgumentNullException
or ArgumentOutOfRangeException and return void.
For three of my other methods, they are all designed to get xml strings.
However, since the return value is int to indicate success/failure the design
calls to pass these in by reference. This seems to be an example of where
exceptions could be real useful. First you can design the methods to return
what their names imply they return and get rid of the by reference parameters.
Secondly, the return string could have fault formats predefined for NO_DATA
or some other expected results. Thirdly, exceptions could be used for all
unexpected events.
Does that sound reasonable to you?
>In either case, you shouldn't return error codes AND throw exceptions -
for
>the *same* problems. That's just redundant, confusing, and won't work to
>begin with.
I understand.
Thanks Rob,
Michael
-
Re: Exceptions vs. Return Values
I'll tell ya my take on all this and keep it real simple.
In general, there are two paths your code can follow. One path is normal
execution. The other is when an exception occurs.
In normal execution, you would expect the user to seamlessly type in a name
and password, and if there is a problem, you prompt the user again. If the
authentication can't take place, then you throw an exception.
Why?
Well, if you return a result, that forces the caller to check the result.
It forces the caller of the caller to check the result. It forces the caller
of the caller of the caller to check the result. See what I am getting at?
If you return a value indicating that the user didn't log in correctly, you
have to return that value to everyone concerned, and that could be a deep
call stack. If you are writing a library, the users of your library will
be forced to do the same thing. If anyone fails to return a value, then
you continue normal execution when you really should not. The user could
not log in, so you don't want to continue with the normal path of execution!
If you throw an error, you stop normal execution, and you clean up (using
"finally" or "catch") on the way up the call stack. Anyone using your library
will be able to do the same thing.
So, in short, when a user can't enter the correct password, this is definitely
an "exception" to the normal flow of things, and you may have multiple places
where you want to clean up things.
If you return a value, you are stating that it is "normal" for the user to
enter an invalid password, and people will have to write logic into their
normal code to handle this case at all levels of the code. Clearly, this
is something where structured exception handling can produce cleaner code
all around.
Don't worry about the rumored performance hit. In this case, you probably
can't measure the difference, and you certainly won't notice it.
-
Re: Exceptions vs. Return Values
Jason and Rob,
>
> I'll tell ya my take on all this and keep it real simple.
>
> In general, there are two paths your code can follow. One path is normal
> execution. The other is when an exception occurs.
>
Thanks for your feedback. I discussed this with the designer and I have
convinced him to use exceptions instead of return values. Except in one
case. Oh well, can't win them all.
One of the methods will be called very frequently (the CheckIn method) and
he is nervous that if too many calls come in and generate exceptions the
performance will suffer (I can't imagine why we would have lots of calls
coming in generating exceptions, but that's another story). So we've created
an enumeration to specify 3 valid return codes and everything else will get
an exception. I can live with that.
Thanks,
Michael
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
Forum Rules
|
Top DevX Stories
Easy Web Services with SQL Server 2005 HTTP Endpoints
JavaOne 2005: Java Platform Roadmap Focuses on Ease of Development, Sun Focuses on the "Free" in F.O.S.S.
Wed Yourself to UML with the Power of Associations
Microsoft to Add AJAX Capabilities to ASP.NET
IBM's Cloudscape Versus MySQL
|
Bookmarks