Advertisement

Exception Help please...

Started by May 01, 2001 07:33 AM
22 comments, last by Mithrandir 23 years, 9 months ago
I don''t think there is really a right answer, it depends on the application. I can give you an example of how I''ve used it in a professional application.

In one of our applications we have a script-parsing engine (I''ve used this example before on this board). It has a log window to track the status of the script. In the old days, whenever a script error occured (i.e. from the user writing the script or from hardware failing), the function that experienced the failure would manually open the log, write to it, and then return a -1 from the function. Functions had to propagate their return values all the way up the call chain to the script parser, which would finally quit if it detected a bad return value.

What I''ve did was replace this mechanism with exceptions; the reason for the error is thrown, and then the script parser can print out a standard error message and halt the script. This was nice because the script function didn''t know where it was in the script (file xxx, line yyy), but the parser did; it even knew the name of the function being called. So we could get error messages like "Error in function fff (file xxx, line yyy): %s", where %s would be copied from the thrown exception. Before, each function had to log a message like "Error in function (me): reason"; now each function just has to throw runtime_error ("reason");

So here''s an overview of the program''s error structure:
- each function throws an error object consisting of a string; that string describes the reason for the error without any extra information.
- the script parser calls script functions wrapped in a try/catch block. The catch block knows the name of the function called, the parameters, the script filename and line number; all these can be appended to the log message if desired.

What you have is a very robust way to control error flow through this script parser, and you don''t have to "waste" the return values from script functions, or keep an error status flag, or anything old-school like that.

Now, here''s where you get into problems:
This system is fine for release code. However, user script errors are not the only errors that occur. These scripts interface hardware, lots of times through libraries, and when that happens, we would really like the debugger to halt when it hits the throw and we can see what went wrong. Unfortunately, since we have that catch block in there, the program will continue merrily along its way, catching the error before you get a chance to break in.

What we finally decided to do was put #ifndef _DEBUG guards around the try/catch parts of the script parser. This way, if there was an exception thrown while debugging, the debugger would break and we could look at what went wrong. However, for release, you have full try/catch protection. The problem with this is, if you mistype something in your test script, instead of getting an error message, the debugger breaks (which is annoying as hell).

In retrospect, it would have been better to create two different exceptions--one for script errors and one for other errors. That way, we could always leave in the handler for script errors to be reported to the log window, but other errors could be conditionally caught or not, depending on debug or release mode. Oh well, it was my first attempt at using exceptions.

Long-winded, yes, but in summary: exceptions are a tool, and they can probably be used in as many ways as inheritance can (anybody who thinks inheritence can only be used to make a "is-a" relationship needs to read Design Patterns--it''s much, much more complicated than that). I don''t think there are any hard-and-fast answers, so you''ll just have to figure out what''s right for the current application. Best of luck.
Here''s an interesting link I found in the MSDN library: http://msdn.microsoft.com/library/welcome/dsmsdn/deep051099.htm. It''s online column called Deep C++ that has 17 articles on exception handling in both C and C++. It also discusses the limitations and features of the VC++ 6 new and delete operators.
Advertisement
You could ''intercept'' the default handling for the new allocation failure by using set_new_handler() so that it throws instead of returning NULL.
"after many years of singularity, i'm still searching on the event horizon"
quote:

I ended my last column with this wish: When a newed object does not fully construct, its storage should be freed automatically. Fortunately, the C++ Standard Committee added this very capability to the language. Unfortunately, this addition came fairly late in the language''s evolution, and many compilers don''t yet support it. Fortunately, Visual C++ versions 5.0 and 6.0 both support such auto-deletion (although, as we''ll see, version 5.0''s support is incomplete).




http://msdn.microsoft.com/library/default.asp?URL=/library/welcome/dsmsdn/deep01062000.htm


finally found the exact answer

===============================================
But as for me, hungry oblivion
Devour me quick, accept my orison
My earnest prayers Which do importune thee,
With gloomy shade of thy still empery,
To vail both me and my poesy
This is my signature. There are many like it, but this one is mine. My signature is my best friend. It is my life. I must master it as I must master my life. My signature, without me, is useless. Without my signature, I am useless.

This topic is closed to new replies.

Advertisement