Click here to Skip to main content
14,974,809 members
Articles / Operating Systems / Windows
Article
Posted 11 Oct 2006

Tagged as

Stats

35.5K views
8 bookmarked

Not All Exceptions Are Errors

Rate me:
Please Sign up or sign in to vote.
3.14/5 (12 votes)
11 Oct 2006CPOL3 min read
Not all exceptions are errors. Many developers have incorrectly been taught or assume that all exceptions are errors. In fact, a key clue is that they are called exceptions and not errors.

Introduction

Not all exceptions are errors. Many developers have incorrectly been taught or assume that all exceptions are errors. In fact, a key clue is that they are called exceptions and not errors.

Dictionary.com defines an exception as something excepted; an instance or case not conforming to the general rule. Exceptions in code are used to modify standard program flow (i.e. the general rule) and communicate information to a higher calling level where they are trapped.

.NET, Delphi, C++ and Java all treat exceptions with the same rule and many code bases use exceptions for many tasks other than to signal errors. While signalling error conditions is the most common use of exceptions, it is not the only proper use. If errors were the only proper use, we would use the older term that Visual Basic and others used of error handling, instead of exception handling.

Exceptions

Exceptions can also be used to return status information. Imagine a large framework where the call stack is very deep, yet you need to exit out to the root and communicate some condition such as a cancel request from a user.

Should you modify each and every possible method that this can occur in? Doing so would require adding additional flags to each and every method signature possibly even as a reference argument, or creating a global flag in a static. Neither are good approaches. Just imagine how many if statements this would require and the impact to the code in additional complexity and noise.

Imagine the following call stack:

Button1Click
DoSomething
DoSomethingElse
DoSomethingDeeper

Which is better? Modifying all three called methods to pass back a flag the user has cancelled? Or simply throw a typed exception in DoSomethingDeeper and let Button1Click catch it? Using an exception also allows generic resuse by any caller without imposing any abnormal prerequisites.

A cancel exception can be defined and easily thrown from anywhere. This exception is easily caught from the calling code, and has no impact on altering any other code to check for global flags or passed reference arguments. It also handles all program flow properly. If code needs to react to this condition, it can trap and then rethrow the exception. If you have already built in proper exception handling code for errors, usually the same code applies.

But is the user requesting a cancel operation and error? No. But it is an exception. There are many more examples of such behaviour. NUnit uses such exceptions, as does Indy Sockets (Connection closed gracefully), and Delphi's RTL (EAbort).

And Errors?

Errors are things that we do try to prevent, while exceptions may occur on purpose. Errors are things like "Not enough disk space", "Out of memory", "Cannot reach server".

Errors are things that can happen, but do not occur intentionally except during testing. Errors occur when something is wrong, but exceptions can occur also when things are correct but need "exceptional" attention. Think of an exception like an interrupt in hardware. Interrupts are used for error conditions as well, but they are also used to signal network activity, the reset button, and more.

Proceed Slowly

Just because exceptions can be used for signalling something, their main purpose is altering normal program flow. They should not be used as general purpose signalling mechanisms. Exceptions themselves should be used as the exception, not the rule.

Throwing an exception is costly, relatively speaking. Exceptions are not fast mechanisms, nor need they be. You should not throw exceptions inside a loop, unless the exception also causes an exit of the loop. However used in a context such as a user cancelling processing, the overhead is one time and insignificant. In such cases, an exception will still be far faster than executing additional logic code you would have to write.

If the function is an endpoint function and an "exception" is likely, you can implement it like TryParse. However this only works for endpoint functions, not in examples like the user cancel scenario.

History

  • 11th October, 2006: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Chad Z. Hower, a.k.a. Kudzu
"Programming is an art form that fights back"

I am a former Microsoft Regional DPE (MEA) covering 85 countries, former Microsoft Regional Director, and 10 Year Microsoft MVP.

I have lived in Bulgaria, Canada, Cyprus, Switzerland, France, Jordan, Russia, Turkey, The Caribbean, and USA.

Creator of Indy, IntraWeb, COSMOS, X#, CrossTalk, and more.

Comments and Discussions

 
GeneralMy vote of 5 Pin
Sergey Alexandrovich Kryukov26-Jan-11 15:01
mvaSergey Alexandrovich Kryukov26-Jan-11 15:01 
GeneralMy vote of 1 Pin
kane10-Jul-09 6:56
Memberkane10-Jul-09 6:56 
GeneralRe: My vote of 1 Pin
Thoits19-Mar-10 8:37
MemberThoits19-Mar-10 8:37 
GeneralRe: My vote of 1 Pin
Thoits19-Mar-10 11:32
MemberThoits19-Mar-10 11:32 
GeneralInteresting Pin
Rei Miyasaka11-Oct-06 4:41
MemberRei Miyasaka11-Oct-06 4:41 
GeneralRe: Interesting Pin
Chad Z. Hower aka Kudzu11-Oct-06 5:10
MemberChad Z. Hower aka Kudzu11-Oct-06 5:10 
GeneralRe: Interesting Pin
Sergey Alexandrovich Kryukov26-Jan-11 16:14
mvaSergey Alexandrovich Kryukov26-Jan-11 16:14 
GeneralSignalling via an Exception is bad Pin
Alois Kraus11-Oct-06 2:32
MemberAlois Kraus11-Oct-06 2:32 
I do not agree that you can use exceptions as signalling construct. There is massive overhead involved when you use exceptions as signaling mechanism.
Especially when you design a framework this design will lead to desastrous performance since you cannot tell in advance how many signals you will have to handle. It all depends how your client will use you.
More info can be found at Ricos Blog: http://blogs.gotdotnet.com/ricom/archive/2006/09/25/771142.aspx

The Design Guidelines http://blogs.msdn.com/kcwalina/archive/2005/03/16/396787.aspx
clearly state in rule three that you should not do that.

Even the .NET developers had to rethink their exception throwing sometimes because the performance penalty was just too high. Customers reported very slow application startups when the configuration file did contain invalid data. It turned out that the config files were parsed with Int.Parse(cfgValue) which caused a massive amount of exceptions if somewhere was an error inside the config file.
To prevent this with .NET 2.0 a new function Int.TryParse was introduced which will never throw an exception but instead returns a bool variable.

You did nowhere state the performance costs when you use exceptions as signaling construct. This will lead many people down the wrong path until they discover what the danger of this approach is.

Yours,

Alois Kraus
GeneralRe: Signalling via an Exception is bad Pin
Chad Z. Hower aka Kudzu11-Oct-06 2:39
MemberChad Z. Hower aka Kudzu11-Oct-06 2:39 
GeneralRe: Signalling via an Exception is bad Pin
Chad Z. Hower aka Kudzu11-Oct-06 5:07
MemberChad Z. Hower aka Kudzu11-Oct-06 5:07 
GeneralRe: Signalling via an Exception is bad Pin
Alois Kraus11-Oct-06 12:16
MemberAlois Kraus11-Oct-06 12:16 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.