home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #31 / NN_1992_31.iso / spool / comp / lang / cplus / 18352 < prev    next >
Encoding:
Text File  |  1992-12-23  |  4.7 KB  |  121 lines

  1. Newsgroups: comp.lang.c++
  2. Path: sparky!uunet!rational.com!thor!rmartin
  3. From: rmartin@thor.Rational.COM (Bob Martin)
  4. Subject: Re: Complexity in the eyes...V2.0
  5. Message-ID: <rmartin.725127803@thor>
  6. Keywords: error errorstack
  7. Sender: news@rational.com
  8. Organization: Rational
  9. References: <1992Dec17.042207.8150@tagsys.com> <rmartin.724631935@thor> <1992Dec23.031930.15291@tagsys.com>
  10. Date: Wed, 23 Dec 1992 16:23:23 GMT
  11. Lines: 108
  12.  
  13. andrew@tagsys.com (Andrew Gideon) writes:
  14.  
  15. |If I understand your proposal, you'd have me add an ordered collection
  16. |of "parameters" to the base error atom class?  Interesting thought.
  17.  
  18. |Well, let me describe my vision of the error atom - something that I
  19. |stayed away from in previous posts.
  20.  
  21. |The base error atom class ErrorAtom provides virtual methods
  22. |like theSeverity(), theMessage(), isWarning(), etc.  Each module
  23. |(or some other partition of code) provides a subtype of the error
  24. |atom for a specific domain of errors.  
  25.  
  26. |So instances of the DeviceErrorAtom class might contain a severity
  27. |value and an offset into an array of error messages.  This array would
  28. |be a class member (static member).  This provides for easy copying of
  29. |atoms, nicely partitioned error spaces, a good starting point for user
  30. |documentation, etc.
  31.  
  32. I was responsible for the error system in a project about a year ago.
  33. There were several similarities between what you describe and what I
  34. implemented.  I had a base class called Error.  Error was a concrete
  35. class, but could not be constructed in the "Errored" form, it could
  36. only be constructed in the "OK" form.  It offered an operator void* as
  37. in iostream so that you could use the following syntax
  38.  
  39.     Error myError;
  40.     .....
  41.     if (myError)
  42.         .....
  43.  
  44. Users of Error subclassed their own type of errors.  Each subclass was
  45. associated with an unique id code which effectively identified an
  46. array of error messages.  The constructor for these subclasses
  47. required an argument which was the identifier of the error.
  48. Effectively, this was the index of the error message within the array
  49. belonging to that subclass.
  50.  
  51. So, an error might be declared as follows:
  52.  
  53. FileError ferr(CANT_OPEN);
  54.  
  55. Arguments could be added to errors using operator<<, thus:
  56.  
  57. ferr << fileName; // add the file name
  58. ferr << errno;    // add the o/s error code.
  59.  
  60. There was no limit to the number of arguments that could be added.  
  61.  
  62. Error messages were designed so that they could be supplied in
  63. dictionaries.  The idea was that the product might have to be shiped
  64. to many different countries, and the errors might need to be written
  65. in different languages.  In order to format the errors and their
  66. arguments we invented a sprintf-like syntax for embedding the
  67. arguments into the errors.  i.e.
  68.  
  69.     "The file: %1s could not be opened due to error code %2d."
  70.  
  71. Note the digit which specified the ordinal position of the argument.
  72.  
  73. The class Error allowed copy semantics, so that you could create a
  74. FileError but return it as an Error.  Thus Error object could be
  75. passed up the calling or exception chain without the higher levels of
  76. the code knowing the kind of error.  You could also create vanilla
  77. errors and use assignment to copy a derived error into it.
  78.  
  79.     Error err = ferr;
  80.  
  81. Lastly, we created the concept of an ErrorManager.  An ErrorManager is
  82. an object which knows what to do with an error.  Some errors should be
  83. logged to a file, others posted in dialog boxes in a gui.  Still
  84. others should be written to standard error.  Thus we created
  85. subclasses of ErrorManager that know how to interpret an error and
  86. then output it.  Thus the syntax:
  87.  
  88.     ErrorManager em;
  89.     Error err;
  90.     em.Raise(err);
  91.  
  92. This would tell the ErrorManager em to output the error err.
  93. Subclasses of ErrorManager such as LogErrorManager or GuiErrorManager
  94. would be created by the highest levels of the code and then passed
  95. down to the middle levels where errors were raised.  Errors would
  96. percolate up from the low levels of the code to these middle layers
  97. and be raised.  This allowed us to link libraries which raised errors
  98. into applications which were gui driven, console driven or batch jobs
  99. which logged errors.  
  100.  
  101. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  102.  
  103. The upshot of all this is that, for some applications complex error
  104. management is a necessity.  For such applications, it is best if the
  105. complexity is encapsulated far away from the users of the error
  106. system.  In our case, users could create and raise errors with
  107. relative ease.  They had lots of flexibility to add arguments to their
  108. errors.  But the burden of managing and disposing of the errors was
  109. well encapsulated.
  110.  
  111.  
  112.  
  113.  
  114.  
  115.  
  116. --
  117. Robert Martin                        Training courses offered in:
  118. R. C. M. Consulting                       Object Oriented Analysis
  119. 2080 Cranbrook Rd.                        Object Oriented Design
  120. Green Oaks, Il 60048 (708) 918-1004       C++
  121.