home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.lang.c++
- Path: sparky!uunet!rational.com!thor!rmartin
- From: rmartin@thor.Rational.COM (Bob Martin)
- Subject: Re: Complexity in the eyes...V2.0
- Message-ID: <rmartin.725127803@thor>
- Keywords: error errorstack
- Sender: news@rational.com
- Organization: Rational
- References: <1992Dec17.042207.8150@tagsys.com> <rmartin.724631935@thor> <1992Dec23.031930.15291@tagsys.com>
- Date: Wed, 23 Dec 1992 16:23:23 GMT
- Lines: 108
-
- andrew@tagsys.com (Andrew Gideon) writes:
-
- |If I understand your proposal, you'd have me add an ordered collection
- |of "parameters" to the base error atom class? Interesting thought.
-
- |Well, let me describe my vision of the error atom - something that I
- |stayed away from in previous posts.
-
- |The base error atom class ErrorAtom provides virtual methods
- |like theSeverity(), theMessage(), isWarning(), etc. Each module
- |(or some other partition of code) provides a subtype of the error
- |atom for a specific domain of errors.
-
- |So instances of the DeviceErrorAtom class might contain a severity
- |value and an offset into an array of error messages. This array would
- |be a class member (static member). This provides for easy copying of
- |atoms, nicely partitioned error spaces, a good starting point for user
- |documentation, etc.
-
- I was responsible for the error system in a project about a year ago.
- There were several similarities between what you describe and what I
- implemented. I had a base class called Error. Error was a concrete
- class, but could not be constructed in the "Errored" form, it could
- only be constructed in the "OK" form. It offered an operator void* as
- in iostream so that you could use the following syntax
-
- Error myError;
- .....
- if (myError)
- .....
-
- Users of Error subclassed their own type of errors. Each subclass was
- associated with an unique id code which effectively identified an
- array of error messages. The constructor for these subclasses
- required an argument which was the identifier of the error.
- Effectively, this was the index of the error message within the array
- belonging to that subclass.
-
- So, an error might be declared as follows:
-
- FileError ferr(CANT_OPEN);
-
- Arguments could be added to errors using operator<<, thus:
-
- ferr << fileName; // add the file name
- ferr << errno; // add the o/s error code.
-
- There was no limit to the number of arguments that could be added.
-
- Error messages were designed so that they could be supplied in
- dictionaries. The idea was that the product might have to be shiped
- to many different countries, and the errors might need to be written
- in different languages. In order to format the errors and their
- arguments we invented a sprintf-like syntax for embedding the
- arguments into the errors. i.e.
-
- "The file: %1s could not be opened due to error code %2d."
-
- Note the digit which specified the ordinal position of the argument.
-
- The class Error allowed copy semantics, so that you could create a
- FileError but return it as an Error. Thus Error object could be
- passed up the calling or exception chain without the higher levels of
- the code knowing the kind of error. You could also create vanilla
- errors and use assignment to copy a derived error into it.
-
- Error err = ferr;
-
- Lastly, we created the concept of an ErrorManager. An ErrorManager is
- an object which knows what to do with an error. Some errors should be
- logged to a file, others posted in dialog boxes in a gui. Still
- others should be written to standard error. Thus we created
- subclasses of ErrorManager that know how to interpret an error and
- then output it. Thus the syntax:
-
- ErrorManager em;
- Error err;
- em.Raise(err);
-
- This would tell the ErrorManager em to output the error err.
- Subclasses of ErrorManager such as LogErrorManager or GuiErrorManager
- would be created by the highest levels of the code and then passed
- down to the middle levels where errors were raised. Errors would
- percolate up from the low levels of the code to these middle layers
- and be raised. This allowed us to link libraries which raised errors
- into applications which were gui driven, console driven or batch jobs
- which logged errors.
-
- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-
- The upshot of all this is that, for some applications complex error
- management is a necessity. For such applications, it is best if the
- complexity is encapsulated far away from the users of the error
- system. In our case, users could create and raise errors with
- relative ease. They had lots of flexibility to add arguments to their
- errors. But the burden of managing and disposing of the errors was
- well encapsulated.
-
-
-
-
-
-
- --
- Robert Martin Training courses offered in:
- R. C. M. Consulting Object Oriented Analysis
- 2080 Cranbrook Rd. Object Oriented Design
- Green Oaks, Il 60048 (708) 918-1004 C++
-