cea165f466be0c6b6f74387db21263cb57667c75
[kivitendo-erp.git] / modules / fallback / Exception / Lite.pod
1 =head1 NAME
2
3 Exception::Lite - light weight exception handling class with smart
4 stack tracing, chaining, and localization support.
5
6 =head1 SYNOPSIS
7
8    # --------------------------------------------------------
9    # making this module available to your code
10    # --------------------------------------------------------
11
12    #Note: there are NO automatic exports
13
14    use Exception::Lite qw(declareExceptionClass
15                           isException
16                           isChainable
17                           onDie
18                           onWarn);
19
20    # imports only: declareExceptionClass isException isChainable
21    use Exception::Lite qw(:common);
22
23    # imports all exportable methods listed above
24    use Exception::Lite qw(:all);
25
26
27    # --------------------------------------------------------
28    # declare an exception class
29    # --------------------------------------------------------
30
31    # no format rule
32    declareExceptionClass($sClass);
33    declareExceptionClass($sClass, $sSuperClass);
34
35    # with format rule
36    declareExceptionClass($sClass, $aFormatRule);
37    declareExceptionClass($sClass, $sSuperClass, $aFormatRule);
38
39    # with customized subclass
40    declareExceptionClass($sClass, $sSuperClass, 1);
41    declareExceptionClass($sClass, $aFormatRule, 1);
42    declareExceptionClass($sClass, $sSuperClass, $aFormatRule, 1);
43
44    # --------------------------------------------------------
45    # throw an exception
46    # --------------------------------------------------------
47
48    die $sClass->new($sMsg, $prop1 => $val1, ...);  #no format rule
49    die $sClass->new($prop1 => $val1, ...);         #has format rule
50
51    #-or-
52
53    $e = $sClass->new($sMsg, $prop1 => $val1, ...); #no format rule
54    $e = $sClass->new($prop1 => $val1, ...);        #has format rule
55
56    die $e;
57
58    # --------------------------------------------------------
59    # catch and test an exception
60    # --------------------------------------------------------
61
62    # Note: for an explanation of why we don't use if ($@)... here,
63    # see Catching and Rethrowing exceptions below
64
65    eval {
66      .... some code that may die here ...
67      return 1;
68    } or do {
69      my $e=$@;
70
71      if (isException($e, 'Class1')) {
72        ... do something ...
73      } elsif (isExcption($e, 'Class2')) {
74         ... do something else ...
75      }
76    };
77
78    isException($e);        # does $e have the above exception methods?
79    isException($e,$sClass) # does $e belong to $sClass or a subclass?
80
81    # --------------------------------------------------------
82    # getting information about an exception object
83    # --------------------------------------------------------
84
85    $e->getMessage();
86    $e->getProperty($sName);
87    $e->isProperty($sName);
88    $e->replaceProperties($hOverride);
89
90    $e->getPid();
91    $e->getPackage();
92    $e->getTid();
93
94    $e->getStackTrace();
95    $e->getFrameCount();
96    $e->getFile($i);
97    $e->getLine($i);
98    $e->getSubroutine($i);
99    $e->getArgs($i);
100
101    $e->getPropagation();
102    $e->getChained();
103
104
105    # --------------------------------------------------------
106    # rethrowing exceptions
107    # --------------------------------------------------------
108
109    # using original properties and message
110
111    $@=$e; die;         # pure Perl way (reset $@ in case wiped out)
112
113    die $e->rethrow();  # same thing, but a little less cryptic
114
115
116    # overriding original message/properties
117
118    die $e->rethrow(path=>$altpath, user=>$nameReplacingId);
119
120
121    # --------------------------------------------------------
122    # creation of chained exceptions (one triggered by another)
123    # (new exception with "memory" of what caused it and stack
124    # trace from point of cause to point of capture)
125    # --------------------------------------------------------
126
127    isChainable($e);        # can $e be used as a chained exception?
128
129    die $sClass->new($e, $sMsg, $prop1 => $val1, ...);#no format rule
130    die $sClass->new($e, $prop1 => $val1, ...);       #has format rule
131
132    # --------------------------------------------------------
133    # print out full message from an exception
134    # --------------------------------------------------------
135
136    print $e                         # print works
137    warn $e                          # warn works
138    print "$e\n";                    # double quotes work
139    my $sMsg=$e."\n"; print $sMsg;   # . operator works
140
141
142    # --------------------------------------------------------
143    # global control variables (maybe set on the command line)
144    # --------------------------------------------------------
145
146    $Exception::Lite::STRINGIFY   #set rule for stringifying messages
147
148       = 1;        # message and file/line where it occured
149       = 2;        # 1 + what called what (simplified stack trace)
150       = 3;        # 2 + plus any chained exceptions and where message
151                   # was caught, if propagated and rethrown
152       = 4;        # 3 + arguments given to each call in stack trace
153       = coderef   # custom formatting routine
154
155    $Exception::Lite::TAB   # set indentation for stringified
156                            # messages, particularly indentation for
157                            # call parameters and chained exceptions
158
159    $Exception::Lite::FILTER
160      = 0         # see stack exactly as Perl does
161      = 1         # remove frames added by eval blocks
162      = coderef   # custom filter - see getStackTrace for details
163
164    # --------------------------------------------------------
165    # controlling the stack trace from the command line
166    # --------------------------------------------------------
167
168    perl -mException::Lite=STRINGIFY=1,FILTER=0,TAB=4
169    perl -m'Exception::Lite qw(STRINGIFY=1 FILTER=0 TAB=4)'
170
171    # --------------------------------------------------------
172    # built in exception classes
173    # --------------------------------------------------------
174
175    # generic wrapper for converting exception strings and other
176    # non-Exception::Lite exceptions into exception objects
177
178    Exception::Class::Any->new($sMessageText);
179
180 To assist in debugging and testing, this package also includes
181 two methods that set handlers for die and warn. These methods
182 should I<only> be used temporarily during active debugging. They
183 should not be used in production software, least they interfere
184 with the way other programmers using your module wish to do their
185 debugging and testing.
186
187    # --------------------------------------------------------
188    # force all exceptions/warnings to use Exception::Lite to
189    # print out messages and stack traces
190    # --------------------------------------------------------
191
192    # $stringify is the value for EXCEPTION::Lite::STRINGIFY
193    # that you want to use locally to print out messages. It
194    # will have no effect outside of the die handler
195
196    Exception::Lite::onDie($stringify);
197    Exception::Lite::onWarn($stringify);
198
199 =head1 DESCRIPTION
200
201 The C<Exception::Lite> class provides an easy and very light weight
202 way to generate context aware exceptions.  It was developed because
203 the exception modules on CPAN as of December,2010 were heavy on
204 features I didn't care for and did not have the features I most
205 needed to test and debug code efficiently.
206
207 =head2 Features
208
209 This module provides a light weight but powerful exception class
210 that
211
212 =over 
213
214 =item *
215
216 provides an uncluttered stack trace that clearly shows what
217 called what and what exception triggered what other exception.
218 It significantly improves on the readability of the stack trace
219 dumps provided by C<carp> and other exception modules on
220 CPAN (as of 12/2010).  For further discussion and a sample, see
221 L</More intelligent stack trace>.
222
223 =item *
224
225 gives the user full control over the amount of debugging
226 information displayed when exceptions are thrown.
227
228 =item *
229
230 permits global changes to the amount of debugging information
231 displayed via the command line.
232
233 =item *
234
235 closely integrates exception classes, messages, and properties
236 so that they never get out of sync with one another.  This in
237 turn eliminates redundant coding and helps reduce the cost of
238 writing,validating and maintaining a set of exceptions.
239
240 =item *
241
242 is easy to retrofit with native language support, even if this
243 need appears late in the development process.This makes it
244 suitable for use with agile development strategies.
245
246 =item *
247
248 act like strings in string context but are in fact objects with
249 a class hierarchy and properties.They can be thrown and rethrown
250 with standard Perl syntax. Like any object, they can be uniquely
251 identified in numeric context where they equal their reference
252 address (the value returned by C<Scalar::Util::refaddr()>.
253
254 =item *
255
256 does not interfere with signal handlers or the normal Perl syntax
257 and the assumptions of Perl operators.
258
259 =item *
260
261 can be easily extended and subclassed
262
263 =back
264
265 =head2 Lightweight how?
266
267 Despite these features C<Exception::Lite> maintains its "lite"
268 status by
269
270 =over
271
272 =item *
273
274 using only core modules
275
276 =item *
277
278 generating tiny exception classes (30-45LOC per class).
279
280 =item *
281
282 eliminating excess baggage by customizing generated classes to
283   reflect the actual needs of exception message generation.  For
284   instance an exception wrapped around a fixed string message would
285   omit code for message/property integration and would be little
286   more than a string tied to a stack trace and property hash.
287
288 =item *
289
290 storing only the minimum amount of stack trace data needed to
291   generate exception messages and avoiding holding onto references
292   from dead stack frames.  (Note: some CPAN modules hold onto
293   actual variables from each frame, possibly interfering with
294   garbage collection).
295
296 =item *
297
298 doing all its work, including class generation and utilities in
299   a single file that is less than half the size of the next smallest
300   similarly featured all-core exception class on CPAN (support for
301   both properties and a class heirarchy).  C<Exception::Lite>
302   contains about 400 lines when developer comments are excluded). The
303   next smallest all core module is L<Exception::Base|Exception::Base>
304   which clocks in at just over 1000 lines after pod and developer
305   comments are excluded).
306
307 =item *
308
309 avoiding a heavy-weight base class.  Code shared by
310   C<Exception::Lite> classes are stored in function calls that total
311   230 or so lines of code relying on nothing but core modules. This
312   is significantly less code than is needed by the two CPAN packages
313   with comparable features.  The all core
314   L<Exception::Base|Exception::Base> class contains 700+ lines of
315   code.  The base class of L<Exception::Class|Exception::Class> has
316   200 lines of its own but drags in two rather large non-core
317   modules as dependencies:  L<Devel::StackTrace|Devel::StackTrace>
318   L<Class::Data::Inheritable|Class::Data::Inheritable>.
319
320 =back
321
322 C<Exception::Lite> has more features (chaining, message/property
323 integration) but less code due to the following factors:
324
325 =over
326
327 =item *
328
329 working with Perl syntax rather than trying to replace it.
330
331 =item *
332
333 using a light approach to OOP - exception classes have just enough
334 and no more OO features than are needed to be categorized by a
335 class, participate in a class heirarchy and to have properties.
336
337 =item *
338
339 respecting separation of concerns. C<Exception::Lite> focuses
340 on the core responsibility of an exception and leaves the bulk of
341 syntax creation (e.g. Try/Catch) to specialist modules like
342 L<Try::Tiny|Try::Tiny>.  Other modules try to double as
343 comprehensive providers of exception related syntactic sugar.
344
345 =item *
346
347 not trying to be the only kind of exception that an application
348 uses.
349
350 =back
351
352 =head1 USAGE
353
354 =head2 Defining Exception Classes
355
356 C<Exception::Lite> provides two different ways to define messages.
357 The first way, without a format rule, lets you compose a freeform
358 message for each exception.  The second way, with a format rule,
359 lets you closely integrate messages and properties and facilitates
360 localization of messages for any packages using your software.
361
362 =head3 Defining freeform messages
363
364 If you want to compose a free form message for each and every
365 exception, the class declaration is very simple:
366
367    declareExceptionClass($sClass);
368    declareExceptionClass($sClass, $sSuperClass);
369
370    # with customized subclass
371    declareExceptionClass($sClass, $sSuperClass, 1);
372
373 C<$sClass> is the name of the exception class.
374
375 C<$sSuperClass> is the name of the superclass, if there is one.
376 The superclass can be any class created by C<Exception::Lite>. It
377 can also be any role class, i.e. a class that has methods but no
378 object data of its own.
379
380 The downside of this simple exception class is that there is
381 absolutely no integration of your messages and any properties that
382 you assign to the exception.  If you would like to see your property
383 values included in the message string,consider using a formatted
384 message instead.
385
386 =head3 Defining formatted messages
387
388 If you wish to include property values in your messages, you need
389 to declare a formatted message class. To do this, you define a
390 format rule and pass it to the constructor:
391
392    $aFormatRule = ['Cannot copy %s to %s', qw(from to) ];
393
394    declareExceptionClass($sClass, $aFormatRule);
395    declareExceptionClass($sClass, $sSuperClass, $aFormatRule);
396
397    # with customized subclass
398    declareExceptionClass($sClass, $aFormatRule, 1);
399    declareExceptionClass($sClass, $sSuperClass, $aFormatRule, 1);
400
401 Format rules are nothing more than a sprintf message string
402 followed by a list of properties in the same order as the
403 placeholders in the message string.  Later on when an exception
404 is generated, the values of the properties will replace the
405 property names.  Some more examples of format rules:
406
407
408    $aFormatRule = ['Illegal argument <%s>: %s', qw(arg reason)];
409    declareExceptionClass('BadArg', $aFormatRule);
410
411    $aFormatRule = ['Cannot open file <%s>> %s', qw(file reason)];
412    declareExceptionClass('OpenFailed', $aFormatRule);
413
414    $sFormatRule = ['Too few %s,  must be at least %s', qw(item min)];
415    declareExceptionClass('TooFewWidgets', $aFormatRule);
416
417
418 Later on when you throw an exception you can forget about the message
419 and set the properties, the class will do the rest of the work:
420
421     die BadArg->new(arg=>$sPassword, reason=>'Too few characters');
422
423
424     open(my $fh, '>', $sFile)
425       or die OpenFailed->new(file=>$sFile, reason=>$!);
426
427 And still later when you catch the exception, you have two kinds
428 of information for the price of one:
429
430     # if you catch BadArg
431
432     $e->getProperty('arg')      # mine
433     $e->getProperty('reason')   # too few characters
434     $e->getMessage()   # Illegal argument <mine>: too few characters
435
436
437     # if you catch OpenFailed
438
439     $e->getProperty('file')     # foo.txt
440     $e->getProperty('reason')   # path not found
441     $e->getMessage()   # Cannot open <foo.txt>: path not found
442
443
444 =head2 Creating and throwing exceptions
445
446 When it comes times to create an exception, you create and
447 throw it like this (C<$sClass> is a placeholder for the name of
448 your exception class);
449
450
451    die $sClass->new($sMsg, prop1 => $val1, ...);  #no format rule
452    die $sClass->new(prop1 => $val1, ...);         #has format rule
453
454    #-or-
455
456    $e = $sClass->new($sMsg, prop1 => $val1, ...); #no format rule
457    $e = $sClass->new(prop1 => $val1, ...);        #has format rule
458
459    die $e;
460
461
462 For example:
463
464    # Freeform exceptions (caller composes message, has message
465    # parameter ($sMsg) before the list of properties)
466
467    close $fh or die UnexpectedException
468      ->new("Couldn't close file handle (huh?): $!");
469
470    die PropertySettingError("Couldn't set property"
471      , prop=>foo, value=>bar);
472
473    # Formatted exceptions (no $sMsg parameter)
474
475    if (length($sPassword) < 8) {
476       die BadArg->new(arg=>$sPassword, reason=>'Too few characters');
477    }
478
479    open(my $fh, '>', $sFile)
480       or die OpenFailed->new(file=>$sFile, reason=>$!);
481
482 In the above examples the order of the properties does not matter.
483 C<Exception::Lite> is using the property names, not the order of
484 the properties to find the right value to plug into the message
485 format string.
486
487 =head2 Catching and testing exceptions
488
489 In Perl there are two basic ways to work with exceptions:
490
491 * native Perl syntax
492
493 * Java like syntax (requires non-core modules)
494
495 =head3 Catching exceptions the Java way
496
497 Java uses the following idiom to catch exceptions:
498
499    try {
500      .... some code here ...
501   } catch (SomeExceptionClass e) {
502     ... error handling code here ...
503   } catch (SomeOtherExceptionClass e) {
504     ... error handling code here ...
505   } finally {
506     ... cleanup code here ...
507   }
508
509 There are several CPAN modules that provide some sort of syntactic
510 sugar so that you can emulate java syntax. The one recommended
511 for C<Exception::Lite> users is L<Try::Tiny|Try::Tiny>.
512 L<Try::Tiny|Try::Tiny> is an elegant class that concerns itself
513 only with making it possible to use java-like syntax.  It can be
514 used with any sort of exception.
515
516 Some of the other CPAN modules that provide java syntax also
517 require that you use their exception classes because the java like
518 syntax is part of the class definition rather than a pure
519 manipulation of Perl syntax.
520
521
522 =head3 Catching exceptions the Perl way
523
524 The most reliable and fastest way to catch an exception is to use
525 C< eval/do >:
526
527    eval {
528      ...
529      return 1;
530    } or do {
531      # save $@ before using it - it can easily be clobbered
532      my $e=$@;
533
534      ... do something with the exception ...
535
536      warn $e;                 #use $e as a string
537      warn $e->getMessage();   # use $e as an object
538    }
539
540
541 The C<eval> block ends with C<return 1;> to insure that successful
542 completion of the eval block never results in an undefined value.
543 In certain cases C<undef> is a valid return value for a statement,
544 We don't want to enter the C<do> block for any reason other than
545 a thrown exception.
546
547 C< eval/do > is both faster and more reliable than the C< eval/if>
548 which is commonly promoted in Perl programming tutorials:
549
550   # eval ... if
551
552   eval {...};
553   if ($@) {....}
554
555 It is faster because the C<do> block is executed if and only
556 if the eval fails. By contrast the C<if> must be evaluated both
557 in cases of succes and failure.
558
559 C< eval/do > is more reliable because the C<do> block is guaranteed
560 to be triggered by any die, even one that accidentally throws undef
561 or '' as the "exception". If an exception is thrown within the C<eval>
562 block, it will always evaluate to C<undef> therefore triggering the
563 C<do> block.
564
565 On the other hand we can't guarentee that C<$@> will be defined
566 even if an exception is thrown. If C<$@> is C<0>, C<undef>, or an
567 empty string, the C<if> block will never be entered.  This happens
568 more often then many programmers realize.  When eval exits the
569 C< eval > block, it calls destructors of any C<my> variables. If
570 any of those has an C< eval > statement, then the value of C<$@> is
571 wiped clean or reset to the exception generated by the destructor.
572
573 Within the C<do> block, it is a good idea to save C<$@> immediately
574 into a variable before doing any additional work.  Any subroutine
575 you call might also clobber it.  Even built-in commands that don't
576 normally set C<$@> can because Perl lets a programmer override
577 built-ins with user defined routines and those user define routines
578 might set C<$@> even if the built-in does not.
579
580 =head3 Testing exceptions
581
582 Often when we catch an exception we want to ignore some, rethrow
583 others, and in still other cases, fix the problem. Thus we need a
584 way to tell what kind of exception we've caught.  C<Exception::Lite>
585 provides the C<isException> method for this purpose.  It can be
586 passed any exception, including scalar exceptions:
587
588    # true if this exception was generated by Exception::Line
589    isException($e);
590
591
592    # true if this exception belongs to $sClass. It may be a member
593    # of the class or a subclass.  C<$sClass> may be any class, not
594    # just an Exception::Lite generated class. You can even use this
595    # method to test for string (scalar) exceptions:
596
597    isException($e,$sClass);
598
599    isException($e,'Excption::Class');
600    isException($e, 'BadArg');
601    isException($e, '');
602
603 And here is an example in action. It converts an exception to a
604 warning and determines how to do it by checing the class.
605
606
607    eval {
608      ...
609      return 1;
610    } or do {
611      my $e=$@;
612      if (Exception::Lite::isException($e)) {
613
614         # get message w/o stack trace, "$e" would produce trace
615         warn $e->getMessage();
616
617      } elsif (Exception::Lite::isException('Exception::Class') {
618
619         # get message w/o stack trace, "$e" would produce trace
620         warn $e->message();
621
622      } elsif (Exception::Lite::isException($e,'')) {
623
624         warn $e;
625      }
626    }
627
628 =head2 Rethrowing exceptions
629
630 Perl doesn't have a C<rethrow> statement.  To reliably rethrow an
631 exception, you must set C<$@> to the original exception (in case it
632 has been clobbered during the error handling process) and then call
633 C<die> without any arguments.
634
635    eval {
636      ...
637      return 1;
638    } or do {
639      my $e=$@;
640
641      # do some stuff
642
643      # rethrow $e
644      $@=$e; die;
645    }
646
647 The above code will cause the exception's C<PROPAGATE> method to
648 record the file and line number where the exception is rethrown.
649 See C<getLine>, C<getFile>, and C<getPropagation> in the class
650 reference below for more information.
651
652 As this Perl syntax is not exactly screaming "I'm a rethrow", 
653 C<Exception::Lite> provides an alternative and hopefully more
654 intuitive way of propagating an exception. There is no magic here,
655 it just does what perl would do had you used the normal syntax,
656 i.e. call the exception's C<PROPAGATE> method.
657
658    eval {
659      ...
660      return 1;
661    } or do {
662      my $e=$@;
663
664      # rethrow $e
665      die $e->rethrow();
666    }
667
668 =head2 Chaining Messages
669
670 As an exception moves up the stack, its meaning may change. For
671 example, suppose a subroutine throws the message "File not open".
672 The immediate caller might be able to use that to try and open
673 a different file.  On the other hand, if the message gets thrown
674 up the stack, the fact that a file failed to open might not
675 have any meaning at all.  That higher level code only cares that
676 the data it needed wasn't available. When it notifies the user,
677 it isn't going to say "File not found", but "Can't run market
678 report: missing data feed.".
679
680 When the meaning of the exception changes, it is normal to throw
681 a new exception with a class and message that captures the new
682 meaning. However, if this is all we do, we lose the original
683 source of the problem.
684
685 Enter chaining.  Chaining is the process of making one exception
686 "know" what other exception caused it.  You can create a new
687 exception without losing track of the original source of the
688 problem.
689
690 To chain exceptions is simple: just create a new exception and
691 pass the caught exception as the first parameter to C<new>. So
692 long as the exception is a non-scalar, it will be interpreted
693 as a chained exception and not a property name or message text
694 (the normal first parameter of C<new>).
695
696 Chaining is efficient, especially if the chained exception is
697 another C<Exception::Lite> exception. It does not replicate
698 the stack trace.  Rather the original stack trace is shorted to
699 include only the those fromes frome the time it was created to
700 the time it was chained.
701
702 Any non-scalar exception can be chained.  To test whether or not
703 a caught exception is chainable, you can use the method
704 C<isChainable>.  This method is really nothing more than
705 a check to see if the exception is a non-scalar, but it helps
706 to make your code more self documenting if you use that method
707 rather than C<if (ref($e))>.
708
709 If an exception isn't chainable, and you still want to chain
710 it, you can wrap the exception in an exception class. You
711 can use the built-in C<Exception::Class::Any> or any class of
712 your own choosing.
713
714    #-----------------------------------------------------
715    # define some classes
716    #-----------------------------------------------------
717
718    # no format rule
719    declareExceptionClass('HouseholdDisaster');
720
721    # format rule
722    declareExceptionClass('ProjectDelay'
723      , ['The project was delayed % days', qw(days)]);
724
725    #-----------------------------------------------------
726    # chain some exceptins
727    #-----------------------------------------------------
728
729    eval {
730      .... some code here ...
731      return 1;
732   } or do {
733     my $e=$@;
734     if (Exception::Lite::isChainable($e)) {
735       if (Exception::Lite::isException($e, 'FooErr') {
736         die 'SomeNoFormatException'->new($e, "Caught a foo");
737       } else {
738         die 'SomeFormattedException'->new($e, when => 'today');
739       }
740     } elsif ($e =~ /fire/) {
741        die 'Exception::Lite::Any'->new($e);
742        die 'SomeFormattedException'->new($e, when => 'today');
743     } else {
744       # rethrow it since we can't chain it
745       $@=$e; die;
746     }
747   }
748
749 =head2 Reading Stack Traces
750
751 At its fullest level of detail, a stack trace looks something
752 like this:
753
754  Exception! Mayhem! and then ...
755
756     thrown  at  file Exception/Lite.t, line 307
757     in main::weKnowBetterThanYou, pid=24986, tid=1
758        @_=('ARRAY(0x83a8a90)'
759           ,'rot, rot, rot'
760           ,'Wikerson brothers'
761           ,'triculous tripe'
762           ,'There will be no more talking to hoos who are not!'
763           ,'black bottom birdie'
764           ,'from the three billionth flower'
765           ,'Mrs Tucanella returns with uncles and cousins'
766           ,'sound off! sound off! come make yourself known!'
767           ,'Apartment 12J'
768           ,'Jo Jo the young lad'
769           ,'the whole world was saved by the smallest of all'
770           )
771     reached via file Exception/Lite.t, line 281
772     in main::notAWhatButAWho
773        @_=()
774     reached via file Exception/Lite.t, line 334 in main::__ANON__
775        @_=()
776     reached via file Exception/Lite.t, line 335 in <package: main>
777        @ARGV=()
778
779     Triggered by...
780     Exception! Horton hears a hoo!
781        rethrown at file Exception/Lite.t, line 315
782
783        thrown  at  file Exception/Lite.t, line 316
784        in main::horton, pid=24986, tid=1
785           @_=('15th of May'
786              ,'Jungle of Nool'
787              ,'a small speck of dust on a small clover'
788              ,'a person's a person no matter how small'
789              )
790        reached via file Exception/Lite.t, line 310 in main::hoo
791           @_=('Dr Hoovey'
792              ,'hoo-hoo scope'
793              ,'Mrs Tucanella'
794              ,'Uncle Nate'
795              )
796        reached via file Exception/Lite.t, line 303
797        in main::weKnowBetterThanYou
798           @_=('ARRAY(0x83a8a90)'
799              ,'rot, rot, rot'
800              ,'Wikerson brothers'
801              ,'triculous tripe'
802              ,'There will be no more talking to hoos who are not!'
803              ,'black bottom birdie'
804              ,'from the three billionth flower'
805              ,'Mrs Tucanella returns with uncles and cousins'
806              ,'sound off! sound off! come make yourself known!'
807              ,'Apartment 12J'
808              ,'Jo Jo the young lad'
809              ,'the whole world was saved by the smallest of all'
810              )
811
812
813 =over
814
815 =item *
816
817 lines begining with "thrown" indicate a line where a new exception
818 was thrown. If an exception was chained, there might be multiple
819 such lines.
820
821 =item *
822
823 lines beginning with "reached via" indicate the path travelled
824 I<down> to the point where the exception was thrown. This is the
825 code that was excuted before the exception was triggered.
826
827 =item *
828
829 lines beginning with "rethrown at" indicate the path travelled
830 I<up> the stack by the exception I<after> it was geenerated. Each
831 line indicates a place where the exception was caught and rethrown.
832
833 =item *
834
835 lines introduced with "Triggered by" are exceptions that were
836 chained together. The original exception is the last of the
837 triggered exceptions.  The original line is the "thrown" line
838 for the original exception.
839
840 =item *
841
842 C<@_> and <C@ARGV> below a line indicates what is left of the
843 parameters passed to a method, function or entry point routine.
844 In ideal circumstances they are the parameters passed to the
845 subroutine mentioned in the line immediately above C<@_>. In
846 reality, they can be overwritten or shifted away between the
847 point when the subroutine started and the line was reached.
848
849 Note: if you use L<Getopt::Long> to process C<@ARGV>, C<@ARGV>
850 will be empty reduced to an empty array. If this bothers you, you
851 can localize <@ARGV> before calling C<GetOptions>, like this:
852
853   my %hARGV;
854   {
855     local @ARGV = @ARGV;
856     GetOptions(\%hARGV,...);
857   }
858
859 =item *
860
861 pid is the process id where the code was running
862
863 =item *
864
865 tid is the thread id where the code was running
866
867 =back
868
869 =head1 SPECIAL TOPICS
870
871 =head2 Localization of error messages
872
873 Rather than treat the error message and properties as entirely
874 separate entities, it gives you the option to define a format string
875 that will take your property values and insert them automatically
876 into your message.  Thus when you generate an exception, you can
877 specify only the properties and have your message automatically
878 generated without any need to repeat the property values in messy
879 C<sprintf>'s that clutter up your program.
880
881 One can localize from the very beginning when one declares the
882 class or later on after the fact if you are dealing with legacy
883 software or developing on an agile module and only implementing
884 what you need now.
885
886 To localize from the get-go:
887
888    # myLookupSub returns the arguments to declareException
889    # e.g.  ('CopyError', [ 'On ne peut pas copier de %s a %s'
890                            , qw(from to)])
891
892    declareExceptionClass( myLookupSub('CopyError', $ENV{LANG}) );
893
894
895    # .... later on, exception generation code doesn't need to
896    # know or care about the language. it just sets the properties
897
898
899     # error message depends on locale:
900     #   en_US:  'Cannot copy A.txt to B.txt'
901     #   fr_FR:  'On ne peut pas copier de A.txt a B.txt'
902     #   de_DE:  'Kann nicht kopieren von A.txt nach B.txt'
903
904     die 'CopyError'->new(from => 'A.txt', to => 'B.txt');
905
906
907 Another alternative if you wish to localize from the get-go is
908 to pass a code reference instead of a format rule array. In this
909 case, C<Exception::Lite> will automatically pass the class name
910 to the subroutine and retrieve the value returned.
911
912
913    # anothherLookupSub has parameters ($sClass) and returns
914    # a format array, for example:
915    #
916    # %LOCALE_FORMAT_HASH = (
917    #    CopyError => {
918    #        en_US => ['Cannot copy %s to %s', qw(from to)]
919    #       ,fr_FR => ['On ne peut pas copier de %s a %s', qw(from to)]
920    #       ,de_DE => ['Kann nicht kopieren von %s nach %s''
921    #                   , qw(from to)]
922    #
923    #    AddError => ...
924    # );
925    #
926    # sub anotherLookupSub {
927    #    my ($sClass) = @_;
928    #    my $sLocale = $ENV{LANG}
929    #    return $LOCALE_FORMAT_HASH{$sClass}{$sLocale};
930    # }
931    #
932
933    declareExceptionClass('CopyError', &anotherLookupSub);
934    declareExceptionClass('AddError', &anotherLookupSub);
935
936
937     # error message depends on locale:
938     #   en_US:  'Cannot copy A.txt to B.txt'
939     #   fr_FR:  'On ne peut pas copier de A.txt a B.txt'
940     #   de_DE:  'Kann nicht kopieren von A.txt nach B.txt'
941
942     die CopyError->new(from => 'A.txt', to => 'B.txt');
943     die AddError->new(path => 'C.txt');
944
945
946 If you need to put in localization after the fact, perhaps for a
947 new user interface you are developing, the design pattern might
948 look like this:
949
950    # in the code module you are retrofitting would be an exception
951    # that lived in a single language world. 
952
953    declareExceptionClass('CopyError'
954      ['Cannot copy %s to %s', [qw(from to)]);
955
956
957    # in your user interface application.
958
959    if (isException($e, 'CopyError') && isLocale('fr_FR')) {
960      my $sFrom = $e->getProperty('from');
961      my $sTo = $e->getProperty('to');
962      warn sprintf('On ne peut pas copier de %s a %s', $sFrom,$sTo);
963    }
964
965 =head2 Controlling verbosity and stack tracing
966
967 You don't need to print out the fully verbose stack trace and in
968 fact, by default you won't.  The default setting, prints out
969 only what called what. To make it easier to see what called what,
970 it leaves out all of the dumps of C<@_> and C<@ARGV>.
971
972 If you want more or less verbosity or even an entirely different
973 trace, C<Exception::Lite> is at your sevice.  It provides a variety
974 of options for controlling the output of the exception:
975
976 * Adjusting the level of debugging information when an exception is
977   thrown by setting C<$Exception::Lite::STRINGIFY>
978   in the program or C<-mException::Lite=STRINGIFY=level> on the
979   command line. This can be set to either a verbosity level or to
980   an exception stringification routine of your own choosing.
981
982 * Control which stack frames are displayed by setting
983   C<$Exception::Lite::FILTER>. By default, only calls within named
984   and anonymous subroutines are displayed in the stack trace. Perl
985   sometimes creates frames for blocks of code within a subroutine.
986   These are omitted by default. If you want to see them, you can
987   turn filterin off. Alternatively you can set up an entirely
988   custon stack filtering rule by assigning a code reference to
989   C<$Exception::Lite::FILTER>.
990
991 * By default, exceptions store and print a subset of the data
992   available for each stack frame. If you would like to display
993   richer per-frame information, you can do that too. See below
994   for details.
995
996 =head3 Verbosity level
997
998 The built-in rules for displaying exceptions as strings offer five
999 levels of detail.
1000
1001 * 0: Just the error message
1002
1003 * 1: the error message and the file/line number where it occured
1004      along with pid and tid.
1005
1006 * 2: the error message and the calling sequence from the point where
1007   the exception was generated to the package or script entry point
1008   The calling sequence shows only file, line number and the name
1009   of the subroutine where the exception was generated. It is not
1010   cluttered with parameters, making it easy to scan.
1011
1012 * 3: similar to 2, except that propagation and chained exceptions
1013   are also displayed.
1014
1015 * 4: same as 3, except that the state of C<@_> or C<@ARGV> at the
1016   time the exception was thrown is also displayed.  usually this
1017   is the parameters that were passed in, but it may include several
1018   leading C<undef> if C<shift> was used to process the parameter
1019   list.
1020
1021 Here are some samples illustrating different level of debugging
1022 information and what happens when the filter is turned off
1023
1024  #---------------------------------------------------
1025  #Sample exception STRINGIFY=0 running on thread 5
1026  #---------------------------------------------------
1027
1028  Exception! Mayhem! and then ...
1029
1030  #---------------------------------------------------
1031  #Sample exception STRINGIFY=1 running on thread 5
1032  #---------------------------------------------------
1033
1034  Exception! Mayhem! and then ...
1035     at  file Exception/Lite.t, line 307 in main::weKnowBetterThanYou, pid=24986, tid=5
1036
1037  #---------------------------------------------------
1038  #Sample exception STRINGIFY=2 running on thread 4
1039  #---------------------------------------------------
1040
1041  Exception! Mayhem! and then ...
1042     at  file Exception/Lite.t, line 307 in main::weKnowBetterThanYou, pid=24986, tid=4
1043     via file Exception/Lite.t, line 281 in main::notAWhatButAWho
1044     via file Exception/Lite.t, line 373 in main::__ANON__
1045     via file Exception/Lite.t, line 374 in <package: main>
1046
1047  #---------------------------------------------------
1048  #Sample exception STRINGIFY=3 running on thread 3
1049  #---------------------------------------------------
1050
1051  Exception! Mayhem! and then ...
1052
1053     thrown  at  file Exception/Lite.t, line 307 in main::weKnowBetterThanYou, pid=24986, tid=3
1054     reached via file Exception/Lite.t, line 281 in main::notAWhatButAWho
1055     reached via file Exception/Lite.t, line 362 in main::__ANON__
1056     reached via file Exception/Lite.t, line 363 in <package: main>
1057
1058     Triggered by...
1059     Exception! Horton hears a hoo!
1060        rethrown at file Exception/Lite.t, line 315
1061
1062        thrown  at  file Exception/Lite.t, line 316 in main::horton, pid=24986, tid=3
1063        reached via file Exception/Lite.t, line 310 in main::hoo
1064        reached via file Exception/Lite.t, line 303 in main::weKnowBetterThanYou
1065
1066  #---------------------------------------------------
1067  #Sample exception STRINGIFY=3 running on thread 2
1068  #FILTER=OFF (see hidden eval frames)
1069  #---------------------------------------------------
1070
1071  Exception! Mayhem! and then ...
1072
1073     thrown  at  file Exception/Lite.t, line 307 in main::weKnowBetterThanYou, pid=24986, tid=2
1074     reached via file Exception/Lite.t, line 281 in main::notAWhatButAWho
1075     reached via file Exception/Lite.t, line 348 in (eval)
1076     reached via file Exception/Lite.t, line 348 in main::__ANON__
1077     reached via file Exception/Lite.t, line 350 in (eval)
1078     reached via file Exception/Lite.t, line 350 in <package: main>
1079
1080     Triggered by...
1081     Exception! Horton hears a hoo!
1082        rethrown at file Exception/Lite.t, line 315
1083
1084        thrown  at  file Exception/Lite.t, line 316 in main::horton, pid=24986, tid=2
1085        reached via file Exception/Lite.t, line 310 in (eval)
1086        reached via file Exception/Lite.t, line 315 in main::hoo
1087        reached via file Exception/Lite.t, line 303 in (eval)
1088        reached via file Exception/Lite.t, line 305 in main::weKnowBetterThanYou
1089
1090  #---------------------------------------------------
1091  #Sample exception STRINGIFY=4 running on thread 1
1092  #FILTER=ON
1093  #---------------------------------------------------
1094
1095  Exception! Mayhem! and then ...
1096
1097     thrown  at  file Exception/Lite.t, line 307 in main::weKnowBetterThanYou, pid=24986, tid=1
1098        @_=('ARRAY(0x83a8a90)'
1099           ,'rot, rot, rot'
1100           ,'Wikerson brothers'
1101           ,'triculous tripe'
1102           ,'There will be no more talking to hoos who are not!'
1103           ,'black bottom birdie'
1104           ,'from the three billionth flower'
1105           ,'Mrs Tucanella returns with Wikerson uncles and cousins'
1106           ,'sound off! sound off! come make yourself known!'
1107           ,'Apartment 12J'
1108           ,'Jo Jo the young lad'
1109           ,'the whole world was saved by the tiny Yopp! of the smallest of all'
1110           )
1111     reached via file Exception/Lite.t, line 281 in main::notAWhatButAWho
1112        @_=()
1113     reached via file Exception/Lite.t, line 334 in main::__ANON__
1114        @_=()
1115     reached via file Exception/Lite.t, line 335 in <package: main>
1116        @ARGV=()
1117
1118     Triggered by...
1119     Exception! Horton hears a hoo!
1120        rethrown at file Exception/Lite.t, line 315
1121
1122        thrown  at  file Exception/Lite.t, line 316 in main::horton, pid=24986, tid=1
1123           @_=('15th of May'
1124              ,'Jungle of Nool'
1125              ,'a small speck of dust on a small clover'
1126              ,'a person's a person no matter how small'
1127              )
1128        reached via file Exception/Lite.t, line 310 in main::hoo
1129           @_=('Dr Hoovey'
1130              ,'hoo-hoo scope'
1131              ,'Mrs Tucanella'
1132              ,'Uncle Nate'
1133              )
1134        reached via file Exception/Lite.t, line 303 in main::weKnowBetterThanYou
1135           @_=('ARRAY(0x83a8a90)'
1136               ,'rot, rot, rot'
1137               ,'Wikerson brothers'
1138               ,'triculous tripe'
1139               ,'There will be no more talking to hoos who are not!'
1140               ,'black bottom birdie'
1141               ,'from the three billionth flower'
1142               ,'Mrs Tucanella returns with Wikerson uncles and cousins'
1143               ,'sound off! sound off! come make yourself known!'
1144               ,'Apartment 12J'
1145               ,'Jo Jo the young lad'
1146               ,'the whole world was saved by the tiny Yopp! of the smallest of all'
1147                 )
1148
1149
1150 =head3 Custom stringification subroutines
1151
1152 The custom stringification subroutine expects one parameter, the
1153 exception to be stringified. It returns the stringified form of
1154 the exception. Here is an example of a fairly silly custom
1155 stringification routine that just prints out the chained messages
1156 without any stack trace:
1157
1158    $Exception::Lite::STRINGIFY = sub {
1159       my $e=$_[0];    # exception is sole input parameter
1160       my $sMsg='';
1161       while ($e) {
1162         $sMsg .= $e->getMessage() . "\n";
1163         $e= $e->getChained();
1164       }
1165       return $sMsg;   # return string repreentation of message
1166   };
1167
1168 =head3 Adding information to the stack trace
1169
1170 By default, each frame of the stack trace contains only the file,
1171 line, containing subroutine, and the state of C<@_> at the time
1172 C<$sFile>,C<$iLine> was reached.
1173
1174 If your custom subroutine needs more information about the stack
1175 than C<Exception::Lite> normally provides, you can change the
1176 contents of the stack trace by assigning a custom filter routine
1177 to C<$Exception::Lite::FILTER>.
1178
1179 The arguments to this subroutine are:
1180
1181
1182    ($iFrame, $sFile, $iLine $sSub, $aArgs, $iSubFrame, $iLineFrame)
1183
1184 where
1185
1186 * C<$sFile> is the file of the current line in that frame
1187
1188 * C<$iLine> is the line number of current line in that frame
1189
1190 * C<$sSub> is the name of the subroutine that contains C<$sFile> and
1191   C<$iLine>
1192
1193 * C<$aArgs> is an array that holds the stringified value of each
1194   member of @_ at the time the line at C<$sFile>, C<$sLine> was
1195   called.  Usually, this is the parameters passed into C<$sSub>,
1196   but may not be.
1197
1198 * C<$iSubFrame> is the stack frame that provided the name of the sub
1199   and the contents of $aArgs.
1200
1201 * C<$iLineFrame> is the stack frame that provided the file and line
1202   number for the frame.
1203
1204 Please be aware that each line of the stack trace passed into the
1205 filter subroutine is a composite drawn from two different frames of
1206 the Perl stack trace, C<$iSubFrame> and C<$iLineFrame>.   This
1207 composition is necessary because the Perl stack trace contains the
1208 subroutine that was called at C<$sFile>, C<$iLine> rather than the
1209 subroutine that I<contains> C<$sFile>,C<$iLine>.
1210
1211 The subroutine returns 0 or any other false value if the stack frame
1212 should be omitted. It returns to 1 accept the default stack frame as
1213 is.  If it accepts the stack frame but wants to insert extra data
1214 in the frame, it returns
1215 C<[$sFile,$iLine,$sSub,$aArgs, $extra1, $extra2, ...]>
1216
1217 The extra data is always placed at the end after the C<$aArgs>
1218 member.
1219
1220 =head3 Stack trace filtering
1221
1222 To avoid noise, by default, intermediate frames that are associated
1223 with a block of code within a subroutine other than an anonymous
1224 sub (e.g. the frame created by C<eval {...} or do {...} >) are
1225 omitted from the stack trace.
1226
1227 These omissions add to readability for most debugging purposes.
1228 In most cases one just wants to see which subroutine called which
1229 other subroutine.  Frames created by eval blocks don't provide
1230 useful information for that purpose and simply clutter up the
1231 debugging output.
1232
1233 However, there are situations where one either wants more or less
1234 stack trace filtering.  Stack filtering can turned on or off or
1235 customized by setting C<$Exception::Lite::FILTER> to any of the
1236 following values:
1237
1238 Normally the filtering rule is set at the start of the program or
1239 via the command line.   It can also be set anywhere in code, with one
1240 caveat: an error handling block.
1241
1242 =over
1243
1244 =item 0
1245
1246 Turns all filtering off so that you see each and every frame
1247 in the stack trace.
1248
1249 =item 1
1250
1251 Turns on filtering of eval frames only (default)
1252
1253 =item C<[ regex1, regex2, ... ]>
1254
1255 A list of regexes. If the fully qualified subroutine name matches
1256 any one of these regular expressions it will be omitted from the
1257 stack trace.
1258
1259 =item C<$regex>
1260
1261 A single regular expression.  If the fully qualified subroutine name
1262 matches this regular expression, it will be omitted from the stack
1263 trace.
1264
1265 =item C<$codeReference>
1266
1267 The address of a named or anonymous routine that returns a boolean
1268 value: true if the frame should be includeed, false if it should be
1269 omitted. For parameters and return value of this subroutine see
1270 L</Adding information to the stack trace>.
1271
1272
1273 =back
1274
1275 If filtering strategies change and an exception is chained, some of
1276 its stack frames might be lost during the chaining process if the
1277 filtering strategy that was in effect when the exception was
1278 generated changes before it is chained to another exception.
1279
1280
1281 =head2 Subclassing
1282
1283 To declare a subclass with custom data and methods, use a three step
1284 process:
1285
1286 =over
1287
1288 =item *
1289
1290 choose an exception superclass.  The choice of superclass follows
1291 the rule, "like gives birth to like".  Exception superclasses that
1292 have formats must have a superclass that also takes a format.
1293 Exception subclasses that have no format, must use an exception.
1294
1295 =item *
1296
1297 call C<declareExceptionClass> with its C<$bCustom> parameter set
1298 to 1
1299
1300 =item *
1301
1302 define a C<_new(...)> method (note the leading underscore _) and
1303 subclass specific methods in a  block that sets the package to
1304 the subclass package.
1305
1306 =back
1307
1308
1309 When the C<$bCustom> flag is set to true, it might be best to think
1310 of C<declareExceptionClass> as something like C<use base> or
1311 C<use parent> except that there is no implicit BEGIN block. Like
1312 both these methods it handles all of the setup details for the
1313 class so that you can focus on defining methods and functionality.
1314
1315 Wnen C<Exception::Lite> sees the C<$bCustom> flag set to true, it
1316 assumes you plan on customizing the class. It will set up inhertance,
1317 and generate all the usual method definition for an C<Exception::Lite>
1318 class. However, on account of C<$bCustom> being true, it will add a
1319 few extra things so that and your custom code can play nicely
1320 together:
1321
1322 =over
1323
1324 =item *
1325
1326 a special hash reserved for your subclsses data. You can get
1327 access to this hash by calling C<_p_getSubclassData()>. You are
1328 free to add, change, or remove entries in the hash as needed.
1329
1330 =item *
1331
1332 at the end of its C<new()> method, it calls
1333 C<< $sClass->_new($self) >>. This is why you must define a C<_new()>
1334 method in your subclass package block. The C<_new> method is
1335 responsible for doing additional setup of exception data. Since
1336 this method is called last it can count on all of the normally
1337 expected methods and data having been set up, including the
1338 stack trace and the message generated by the classes format rule
1339 (if there is one).
1340
1341 =back
1342
1343 For example, suppose we want to define a subclass that accepts
1344 formats:
1345
1346   #define a superclass that accepts formats
1347
1348   declareExceptionClass('AnyError'
1349     , ['Unexpected exception: %s','exception']);
1350
1351
1352   # declare Exception subclass
1353
1354   declareExceptionClass('TimedException', 'AnyError', $aFormatData,1);
1355   {
1356      package TimedException;
1357
1358      sub _new {
1359        my $self = $_[0];  #exception object created by Exception::Lite
1360
1361        # do additional setup of properties here
1362        my $timestamp=time();
1363        my $hMyData = $self->_p_getSubclassData();
1364        $hMyData->{when} = time();
1365     }
1366
1367     sub getWhen {
1368        my $self=$_[0];
1369        return $self->_p_getSubclassData()->{when};
1370     }
1371   }
1372
1373
1374 Now suppose we wish to extend our custom class further.  There is
1375 no difference in the way we do things just because it is a subclass
1376 of a customized C<Exception::Lite> class:
1377
1378   # extend TimedException further so that it
1379   #
1380   # - adds two additional bits of data - the effective gid and uid
1381   #   at the time the exception was thrown
1382   # - overrides getMessage() to include the time, egid, and euid
1383
1384   declareExceptionClass('SecureException', 'TimedException'
1385                        , $aFormatData,1);
1386   {
1387      package TimedException;
1388
1389      sub _new {
1390        my $self = $_[0];  #exception object created by Exception::Lite
1391
1392        # do additional setup of properties here
1393        my $timestamp=time();
1394        my $hMyData = $self->_p_getSubclassData();
1395        $hMyData->{euid} = $>;
1396        $hMyData->{egid} = $);
1397     }
1398
1399     sub getEuid {
1400        my $self=$_[0];
1401        return $self->_p_getSubclassData()->{euid};
1402     }
1403     sub getEgid {
1404        my $self=$_[0];
1405        return $self->_p_getSubclassData()->{egid};
1406     }
1407     sub getMessage {
1408        my $self=$_[0];
1409        my $sMsg = $self->SUPER::getMessage();
1410        return sprintf("%s at %s, euid=%s, guid=%s", $sMsg
1411            , $self->getWhen(), $self->getEuid(), $self->getGuid());
1412     }
1413   }
1414
1415 =head2 Converting other exceptions into Exception::Lite exceptions
1416
1417 If you decide that you prefer the stack traces of this package, you
1418 can temporarily force all exceptions to use the C<Exception::Lite>
1419 stack trace, even those not generated by your own code.
1420
1421 There are two ways to do this:
1422
1423 * production code:  chaining/wrapping
1424
1425 * active debugging: die/warn handlers
1426
1427
1428 =head3 Wrapping and chaining
1429
1430 The preferred solution for production code is wrapping and/or
1431 chaining the exception.  Any non-string exception, even one
1432 of a class not created by C<Exception::Lite> can be chained
1433 to an C<Exception::Lite> exception.
1434
1435 To chain a string exception, you first need to wrap it in
1436 an exception class.  For this purpose you can create a special
1437 purpose class or use the generic exception class provided by
1438 the C<Exception::Lite> module: C<Exception::Lite::Any>.
1439
1440 If you don't want to chain the exception, you can also just
1441 rethrow the wrapped exception, as is.  Some examples:
1442
1443    #-----------------------------------------------------
1444    # define some classes
1445    #-----------------------------------------------------
1446
1447    # no format rule
1448    declareExceptionClass('HouseholdRepairNeeded');
1449
1450    # format rule
1451    declareExceptionClass('ProjectDelay'
1452      , ['The project was delayed % days', qw(days)]);
1453
1454    #-----------------------------------------------------
1455    # chain and/or wrap some exceptins
1456    #-----------------------------------------------------
1457
1458    eval {
1459      .... some code here ...
1460      return 1;
1461   } or do {
1462
1463     my $e=$@;
1464     if (Exception::Lite::isChainable($e)) {
1465       if ("$e" =~ /project/) {
1466
1467          # chain formatted message
1468          die 'ProjectDelay'->new($e, days => 3);
1469
1470       } elsif ("$e" =~ /water pipe exploded/) {
1471
1472          # chain unformatted message
1473          die 'HouseholdRepairNeeded'->new($e, 'Call the plumber');
1474
1475       }
1476     } elsif ($e =~ 'repairman') {   #exception is a string
1477
1478        # wrapping a scalar exception so it has the stack trace
1479        # up to this point, but _no_ chaining
1480        #
1481        # since the exception is a scalar, the constructor
1482        # of a no-format exception class will treat the first
1483        # parameter as a message rather than a chained exception
1484
1485        die 'HouseholdRepairNeeded'->new($e);
1486
1487     } else {
1488
1489        # if we do want to chain a string exception, we need to
1490        # wrap it first in an exception class:
1491
1492        my $eWrapped = Exception::Lite::Any->new($e);
1493        die 'HouseholdRepairNeeded'
1494          ->new($eWrapped, "Call the repair guy");
1495     }
1496   }
1497
1498 =head3 Die/Warn Handlers
1499
1500 Die/Warn handlers provide a quick and dirty way to at Exception::Lite
1501 style stack traces to all warnings and exceptions.  However,
1502 it should ONLY BE USED DURING ACTIVE DEBUGGING.  They should never
1503 be used in production code. Setting these handlers
1504 can interfere with the debugging style and techiniques of other
1505 programmers and that is not nice.
1506
1507 However, so long as you are actiely debugging, setting a die or
1508 warn handler can be quite useful, especially if a third party module
1509 is generating an exception or warning and you have no idea where it
1510 is coming from.
1511
1512 To set a die handler, you pass your desired stringify level or
1513 code reference to C<onDie>:
1514
1515     Exception::Lite::onDie(4);
1516
1517 This is roughly equivalent to:
1518
1519    $SIG{__DIE__} = sub {
1520      $Exception::Lite::STRINGIFY=4;
1521      warn 'Exception::Lite::Any'->new('Unexpected death:'.$_[0])
1522        unless ($^S || Exception::Lite::isException($_[0]));
1523    };
1524
1525 To set a warning handler, you pass your desired stringify level or
1526 code reference to C<onWarn>:
1527
1528     Exception::Lite::onWarn(4);
1529
1530 This is roughly equivalent to:
1531
1532   $SIG{__WARN__} = sub {
1533     $Exception::Lite::STRINGIFY=4;
1534     print STDERR 'Exception::Lite::Any'->new("Warning: $_[0]");
1535   };
1536
1537 Typically these handlers are placed at the top of a test script
1538 like this:
1539
1540   use strict;
1541   use warnings;
1542   use Test::More tests => 25;
1543
1544   use Exception::Lite;
1545   Exception::Lite::onDie(4);
1546   Exception::Lite::onWarn(3);
1547
1548   ... actual testing code here ...
1549
1550
1551
1552 =head1 WHY A NEW EXCEPTION CLASS
1553
1554 Aren't there enough already? Well, no.  This class differs from
1555 existing classes in several significant ways beyond "lite"-ness.
1556
1557 =head2 Simplified integration of properties and messages
1558
1559 C<Exception::Lite> simplifies the creation of exceptions by
1560 minimizing the amount of metadata that needs to be declared for
1561 each exception and by closely integrating exception properties
1562 and error messages.  Though there are many exception modules
1563 that let you define message and properties for exceptions, in
1564 those other modules you have to manually maintain any connection
1565 between the two either in your code or in a custom subclass.
1566
1567 In L<Exception::Class|Exception::Class>, for example, you have to
1568 do something like this:
1569
1570      #... at the start of your code ...
1571      # notice how exception definition and message format
1572      # string constant are in two different places and need
1573      # to be manually coordinated by the programmer.
1574
1575      use Exception::Class {
1576        'Exception::Copy::Mine' {
1577            fields => [qw(from to)];
1578         }
1579         # ... lots of other exceptions here ...
1580      }
1581      my $MSG_COPY='Could not copy A.txt to B.txt";
1582
1583      ... later on when you throw the exception ...
1584
1585      # notice the repetition in the use of exception
1586      # properties; the repetition is error prone and adds
1587      # unnecessary extra typing     
1588
1589      my $sMsg = sprintf($MSG_COPY, 'A.txt', 'B.txt');
1590      Exception::Copy::Mine->throw(error => $sMsg
1591                                   , from => 'A.txt'
1592                                   , to => 'B.txt');
1593
1594
1595 C<Exception::Lite> provides a succinct and easy to maintain
1596 method of declaring those same exceptions
1597
1598     # the declaration puts the message format string and the
1599     # class declaration together for the programmer, thus
1600     # resulting in less maintenence work
1601
1602     declareExceptionClass("Exception::Mine::Copy"
1603        , ["Could not copy %s to %s", qw(from, to) ]);
1604
1605
1606     .... some where else in your code ...
1607
1608
1609     # there is no need to explicitly call sprintf or
1610     # repetitively type variable names, nor even remember
1611     # the order of parameters in the format string or check
1612     # for undefined values. Both of these will produce
1613     # the same error message:
1614     #   "Could not copy A.txt to B.txt"
1615
1616     die "Exception::Mine:Copy"->new(from =>'A.txt', to=>'B.txt');
1617     die "Exception::Mine:Copy"->new(to =>'B.txt', from=>'A.txt');
1618
1619      # and this will politely fill in 'undef' for the
1620      # property you leave out:
1621      #    "Could not copy A.txt to <undef>"
1622
1623      die "Exception::Mine::Copy"->new(from=>'A.txt');
1624
1625
1626 =head2 More intelligent stack trace
1627
1628 The vast majority, if not all, of the exception modules on CPAN
1629 essentially reproduce Carp's presentation of the stack trace. They
1630 sometimes provide parameters to control the level of detail, but
1631 make only minimal efforts, if any, to improve on the quality of
1632 debugging information.
1633
1634 C<Exception::Lite> improves on the traditional Perl stack trace
1635 provided by Carp in a number of ways.
1636
1637 =over
1638
1639 =item *
1640
1641 Error messages are shown in full and never truncated (a problem with
1642   C<Carp::croak>.
1643
1644 =item *
1645
1646 The ability to see a list of what called what without the clutter
1647   of subroutine parameters.
1648
1649 =item *
1650
1651 The ability to see the context of a line that fails rather than
1652 a pinhole snapshot of the line itself. Thus one sees
1653 "at file Foo.pm, line 13 in sub doTheFunkyFunk" rather
1654   than the  contextless stack trace line displayed by nearly every,
1655   if not all Perl stacktraces, including C<Carp::croak>:
1656   "called foobar(...) at line 13 in Foo.pm".
1657   When context rather than line snapshots
1658   are provided, it is often enough simply to scan the list of what
1659   called what to see where the error occurred.
1660
1661 =item *
1662
1663 Automatic filtering of stack frames that do not show the actual
1664 Flow from call to call.  Perl internally creates stack frames for
1665 each eval block.  Seeing these in the stack trace make it harder
1666 to scan the stack trace and see what called what.
1667
1668 =item *
1669
1670 The automatic filtering can be turned off or, alternatively
1671 customized to include/exclude arbitrary stack frames.
1672
1673 =item *
1674
1675 One can chain together exceptions and then print out what exception
1676 triggered what other exception.  Sometimes what a low level module
1677 considers important about an exception is not what a higher level
1678 module considers important. When that happens, the programmer can
1679 create a new exception with a more relevant error message that
1680 "remembers" the exception that inspired it. If need be, one can
1681 see the entire history from origin to destination.
1682
1683 =back
1684
1685 The "traditional" stack trace smushes together all parameters into
1686 a single long line that is very hard to read.  C<Exception::Lite>
1687 provides a much more readable parametr listing:
1688
1689 =over
1690
1691 =item *
1692
1693 They are displayed one per line so that they can be easily read
1694   and distinguished one from another
1695
1696 =item *
1697
1698 The string value <i>and</i> the normal object representation is
1699   shown when an object's string conversion is overloaded. That way
1700   there can be no confusion about whether the actual object or a
1701   string was passed in as a parameter.
1702
1703 =item *
1704
1705 It doesn't pretend that these are the parameters passed to the
1706   subroutine.  It is impossible to recreate the actual values in
1707   the parameter list because the parameter list for any sub is
1708   just C<@_> and that can be modified when a programmer uses shift
1709   to process command line arguments. The most Perl can give (through
1710   its DB module) is the way C<@_> looked at the time the next frame
1711   in the stack was set up.  Instead of positioning the parameters
1712   as if they were being passed to the subroutine, they are listed
1713   below the stacktrace line saying "thrown at in line X in
1714   subroutine Y".  In reality, the "parameters" are the value of
1715   @_ passed to subroutine Y (or @ARGV if this is the entry point),
1716   or what was left of it when we got to line X.
1717
1718 =item
1719
1720 A visual hint that leading C<undef>s in C<@_> or C<@ARGV> may be
1721   the result of shifts rather than a heap of C<undef>s passed into
1722   the subroutine.  This lets the programmer focus on the code, not
1723   on remembering the quirks of Perl stack tracing.
1724
1725 =back
1726
1727 =head1 CLASS REFERENCE
1728
1729 =head2 Class factory methods
1730
1731 =head3 C<declareExceptionClass>
1732
1733    declareExceptionClass($sClass);
1734    declareExceptionClass($sClass, $sSuperclass);
1735    declareExceptionClass($sClass, $sSuperclass, $bCustom);
1736
1737    declareExceptionClass($sClass, $aFormatRule);
1738    declareExceptionClass($sClass, $sSuperclass, $aFormatRule);
1739    declareExceptionClass($sClass, $sSuperclass, $aFormatRule
1740       , $bCustom);
1741
1742 Generates a lightweight class definition for an exception class. It
1743 returns the name of the created class, i.e. $sClass.
1744
1745 =over
1746
1747 =item C<$sClass>
1748
1749 The name of the class (package) to be created.  Required.
1750
1751 Any legal Perl package name may be used, so long as it hasn't
1752 already been used to define an exception or any other class.
1753
1754 =item C<$sSuperclass>
1755
1756 The name of the superclass of C<$sClass>.  Optional.
1757
1758 If missing or undefed, C<$sClass> will be be a base class
1759 whose only superclass is C<UNIVERSAL>, the root class of all Perl
1760 classes.  There is no special "Exception::Base" class that all
1761 exceptions have to descend from, unless you want it that way
1762 and choose to define your set of exception classes that way.
1763
1764 =item C<$aFormatRule>
1765
1766 An array reference describing how to use properties to construct
1767 a message. Optional.
1768
1769 If provided, the format rule is essential the same parameters as
1770 used by sprintf with one major exception: instead of using actual
1771 values as arguments, you use property names, like this:
1772
1773     # insert value of 'from' property in place of first %s
1774     # insert value of 'to' property in place of first %s
1775
1776     [ 'Cannot copy from %s to %s, 'from', 'to' ]
1777
1778 When a format rule is provided, C<Exception::Lite> will auto-generate
1779 the message from the properties whenever the properties are set or
1780 changed. Regeneration is a lightweight process that selects property
1781 values from the hash and sends them to C<sprintf> for formatting.
1782
1783 Later on, when you are creating exceptions, you simply pass in the
1784 property values. They can be listed in any order and extra properties
1785 that do not appear in the message string can also be provided. If
1786 for some reason the value of a property is unknown, you can assign it
1787 C<undef> and C<Exception::Lite> will politely insert a placeholder
1788 for the missing value.  All of the following are valid:
1789
1790
1791     # These all generate "Cannot copy A.txt to B.txt"
1792
1793     $sClass->new(from => 'A.txt', to => 'B.txt');
1794     $sClass->new(to => 'B.txt', from => 'A.txt');
1795     $sClass->new(to => 'B.txt', from => 'A.txt'
1796                  , reason => 'source doesn't exist'
1797                  , seriousness => 4
1798                 );
1799     $sClass->new(reason => 'source doesn't exist'
1800                  , seriousness => 4
1801                  , to => 'B.txt', from => 'A.txt'
1802                 );
1803
1804     # These generate "Cannot copy A.txt to <undef>"
1805
1806     $sClass->new(from => 'A.txt');
1807     $sClass->new(from => 'A.txt', to => 'B.txt');
1808
1809 =item C<$bCustom>
1810
1811 True if the caller intends to add custom methods and/or a custom
1812 constructor to the newly declared class.  This will force the
1813 L<Excepton::Lite> to generate some extra methods and data so
1814 that the subclass can have its own private data area in the class.
1815 See L</Subclassing> for more information.
1816
1817
1818 =back
1819
1820 =head2 Object construction methods
1821
1822 =head3 C<new>
1823
1824     # class configured for no generation from properties
1825
1826     $sClass->new($sMsg);
1827     $sClass->new($sMsg,$prop1 => $val1, ....);
1828     $sClass->new($e);
1829     $sClass->new($e, $sMsg);
1830     $sClass->new($e, $sMsg,$prop1 => $val1, ....);
1831
1832     # class configured to generate messages from properties
1833     # using a per-class format string
1834
1835     $sClass->new($prop1 => $val1, ....);
1836     $sClass->new($e, $prop1 => $val1, ....);
1837
1838
1839 Creates a new instance of exception class C<$sClass>. The exception
1840 may be independent or chained to the exception that triggered it.
1841
1842 =over
1843
1844 =item $e
1845
1846 The exception that logically triggered this new exception.
1847 May be omitted or left undefined.  If defined, the new exception is
1848 considered chained to C<$e>.
1849
1850 =item $sMsg
1851
1852 The message text, for classes with no autogeneration from properties,
1853 that is, classes declared like
1854
1855    declareExceptionClass($sClass);
1856    declareExceptionClass($sClass, $sSuperclass);
1857
1858 In the constructor, C< $sClass->new($e) >>, the message defaults to
1859 the message of C<$e>. Otherwise the message is required for any
1860 class that id declared in the above two ways.
1861
1862 =item $prop1 => $val1
1863
1864 The first property name and its associated value. There can be
1865 as many repetitions of this as there are properties.  All types
1866 of exception classes may have property lists.
1867
1868 =back
1869
1870 If you have chosen to have the message be completely independent
1871 of properties:
1872
1873    declareExceptionClass('A');
1874
1875    # unchained exception - print output "Hello"
1876
1877    my $e1 = A->new("Hello", importance => 'small', risk => 'large');
1878    print "$e1\n";
1879
1880    # chained exception - print output "Hello"
1881
1882    my $e2 = A->new($e1,'Goodbye');
1883
1884    $e2->getChained();                      # returns $e1
1885    print $e1->getMessage();                # outputs "Goodbye"
1886    print $e1;                              # outputs "Goodbye"
1887    print $e2->getChained()->getMessage();  # outputs "Hello"
1888
1889
1890 If you have chosen to have the message autogenerated from properties
1891 your call to C<new> will look like this:
1892
1893    $sFormat ='the importance is %s, but the risk is %s';
1894    declareExceptionClass('B', [ $sFormat, qw(importance risk)]);
1895
1896
1897    # unchained exception
1898
1899    my $e1 = B->new(importance=>'small', risk=>'large');
1900
1901    $e1->getChained();   # returns undef
1902    print "$e1\n";       # outputs "The importance is small, but the
1903                         #   risk is large"
1904
1905    # chained exception
1906
1907    $e2 = B->new($e1, importance=>'yink', risk=>'hooboy');
1908    $e2->getChained();   # returns $e1
1909    "$e2"                # evaluates to "The importance is yink, but
1910                         # the risk is hooboy"
1911    $e2->getMessage()                # same as "$e2"
1912    $e2->getChained()->getMessage(); # same as "$e1"
1913
1914
1915
1916 =head2 Object methods
1917
1918 =head3 C<getMessage>
1919
1920    $e->getMessage();
1921
1922 Returns the messsage, i.e. the value displayed when this exception
1923 is treated as a string.  This is the value without line numbers
1924 stack trace or other information.  It includes only the format
1925 string with the property values inserted.
1926
1927 =head3 C<getProperty>
1928
1929    $e->getProperty($sName);
1930
1931 Returns the property value for the C<$sName> property.
1932
1933 =head3 C<isProperty>
1934
1935    $e->isProperty($sName)
1936
1937 Returns true if the exception has the C<$sName> property, even if
1938 the value is undefined. (checks existance, not definition).
1939
1940 =head3 C<getPid>
1941
1942    $e->getPid();
1943
1944 Returns the process id of the process where the exception was
1945 thrown.
1946
1947 =head3 C<getPackage>
1948
1949    $e->getPackage();
1950
1951 Returns the package contining the entry point of the process, i.e.
1952 the package identified at the top of the stack.
1953
1954
1955 =head3 C<getTid>
1956
1957 Returns the thread where the exception was thrown.
1958
1959    $e->getTid();
1960
1961 =head3 C<getStackTrace>
1962
1963    $e->getStackTrace();
1964
1965 Returns the stack trace from the point where the exception was
1966 thrown (frame 0) to the entry point (frame -1).  The stack trace
1967 is structured as an array of arrays (AoA) where each member array
1968 represents a single lightweight frame with four data per frame:
1969
1970    [0]  the file
1971    [1]  the line number within the file
1972    [2]  the subroutine where the exception was called. File and
1973         line number will be within this subroutine.
1974    [3]  a comma delimited string containing string representations
1975         of the values that were stored in @_ at the time the
1976         exception was thrown. If shift was used to process the
1977         incoming subroutine arguments, @_ will usually contain
1978         several leading undefs.
1979
1980 For more information about each component of a stack frame, please
1981 see the documentation below for the following methods:
1982
1983 * C<getFile>       - explains what to expect in [0] of stack frame
1984
1985 * C<getLine>       - explains what to expect in [1] of stack frame
1986
1987 * C<getSubroutine> - explains what to expect in [2] of stack frame
1988
1989 * C<getArgs>       - explains what to expect in [3] of stack frame
1990
1991 The frame closest to the thrown exception is numbered 0. In fact
1992 frame 0, stores information about the actual point where the exception
1993 was thrown.
1994
1995
1996 =head3 C<getFrameCount>
1997
1998    $e->getFrameCount();
1999
2000 Returns the number of frames in the stack trace.
2001
2002 =head3 C<getFile>
2003
2004    $e->getFile(0);    # gets frame where exception was thrown
2005    $e->getFile(-1);   # gets entry point frame
2006
2007    $e->getFile();     # short hand for $e->getFile(0)
2008    $e->getFile($i);
2009
2010 Without an argument, this method returns the name of the file where
2011 the exception was thrown.  With an argument it returns the name of
2012 the file in the C<$i>th frame of the stack trace.
2013
2014 Negative values of C<$i> will be counted from the entry point with
2015 C<-1> representing the entry point frame, C<-2> representing the
2016 first call made within the script and so on.
2017
2018 =head3 C<getLine>
2019
2020    $e->getLine(0);    # gets frame where exception was thrown
2021    $e->getLine(-1);   # gets entry point frame
2022
2023    $e->getLine();     # short hand for $e->getLine(0)
2024    $e->getLine($i);
2025
2026 Without an argument, this method returns the line number where the
2027 exception was thrown.  With an argument it returns the line number
2028 in the C<$i>th frame of the stack trace.
2029
2030 Negative values of C<$i> will be counted from the entry point with
2031 C<-1> representing the entry point frame, C<-2> representing the
2032 first call made within the script and so on.
2033
2034 =head3 C<getSubroutine>
2035
2036    $e->getSubroutine(0);    # gets frame where exception was thrown
2037    $e->getSubroutine(-1);   # gets entry point frame
2038
2039    $e->getSubroutine();     # short hand for $e->getSubroutine(0)
2040    $e->getSubroutine($i);
2041
2042 Without an argument, this method returns the name of the subroutine
2043 where this exception was created via C<new(...)>.  With an argument
2044 it returns the value of the subroutine (or package entry point) in
2045 the C<$i>th frame of the stack trace.
2046
2047 Negative values of C<$i> will be counted from the entry point with
2048 C<-1> representing the entry point frame, C<-2> representing the
2049 first call made within the script and so on.
2050
2051 Note: This is not the same value as returned by C<caller($i)>. C<caller> returns the name of the subroutine that was being called
2052 at the time of death rather than the containing subroutine.
2053
2054 The subroutine name in array element [2] includes the package name
2055 so it will be 'MyPackage::Utils::doit' and not just 'doit'. In the
2056 entry point frame there is, of course, no containing subroutine so
2057 the value in this string is instead the package name embedded in
2058 the string "<package: packageName>".
2059
2060
2061 =head3 C<getArgs>
2062
2063    $e->getArgs(0);    # gets frame where exception was thrown
2064    $e->getArgs(-1);   # gets entry point frame
2065
2066    $e->getArgs();     # short hand for $e->getArgs(0)
2067    $e->getArgs($i);
2068
2069 Without an argument, this method returns the value of C<@_> (or
2070 C<@ARGV> for an entry point frame) at the time the exception was
2071 thrown.  With an argument it returns the name of
2072 the file in the C<$i>th frame of the stack trace.
2073
2074 Negative values of C<$i> will be counted from the entry point with
2075 C<-1> representing the entry point frame, C<-2> representing the
2076 first call made within the script and so on.
2077
2078  @_, is the best approximation Perl provides for the arguments
2079 used to call the subroutine.  At the start of the subroutine it does
2080 in fact reflect the parameters passed in, but frequently programmers
2081 will process this array with the C<shift> operator which will set
2082 leading arguments to C<undef>. The debugger does not cache the
2083 oiginal value of @_, so all you can get from its stack trace is the
2084 value at the time the exception was thrown, not the value when the
2085 subroutine was entered.
2086
2087 =head3 C<getPropagation>
2088
2089    $e->getPropagation();
2090
2091 Returns an array reference with one element for each time this
2092 exception was caught and rethrown using either Perl's own rethrow
2093 syntax C<$@=$e; die;> or this packages: C<< die->rethrow() >>.
2094
2095 Each element of the array contains a file and line number where
2096 the exception was rethrown:
2097
2098  [0]  file where exception was caught and rethrown
2099  [1]  line number where the exception was caught and rethrown
2100
2101 Note: do not confuse the stack trace with propagation. The stack
2102 trace is the sequence of calls that were made I<before> the
2103 exception was thrown.  The propagation file and line numbers 
2104 refer to where the exception was caught in an exception handling
2105 block I<after> the exception was thrown.
2106
2107 Generally, bad data is the reason behind an exception.  To see
2108 where the bad data came from, it is generally more useful to
2109 look at the stack and see what data was passed down to the point
2110 where the exception was generated than it is to look at where
2111 the exception was caught after the fact.
2112
2113 =head3 C<getChained>
2114
2115    my $eChained = $e->getChained();
2116
2117 Returns the chained exception, or undef if the exception is not
2118 chained.  Chained exceptions are created by inserting the triggering
2119 exception as the first parameter to C<new(...)>.
2120
2121   # class level format
2122   MyException1->new(reason=>'blahblahblah');       #unchained
2123   MyException1->new($e, reason=>'blahblahblah');   #chained
2124
2125   # no format string
2126   MyException1->new('blahblahblah');               #unchained
2127   MyException1->new($e, reason=>'blahblahblah');   #chained
2128
2129
2130 The chained exception can be a reference to any sort of data. It
2131 does not need to belong to the same class as the new exception,
2132 nor does it even have to belong to a class generated by
2133 C<Exception::Lite>. Its only restriction is that it may not be
2134 a scalar(string, number, ec).  To see if an exception
2135 may be chained you can call C<Exception::Lite::isChainable()>:
2136
2137    if (Exception::Lite::isChainable($e)) {
2138       die MyException1->new($e, reason=>'blahblahblah');
2139    } else {
2140
2141       # another alternative for string exceptions
2142       my $eWrapper=MyWrapperForStringExceptions->new($e);
2143       die MyException1->new($eWrapper, reason=>'blahblahblah');
2144
2145       # another alternative for string exceptions
2146       die MyException1->new($eWrapper, reason=>"blahblahblah: $e");
2147    }
2148
2149
2150 =head3 C<rethrow>
2151
2152    $e->rethrow();
2153    $e->rethrow($prop => $newValue);         # format rule
2154
2155    $e->rethrow($newMsg, $p1 => $newValue);  # no format rule
2156    $e->rethrow(undef, $pl => $newValue);    # no format rule
2157    $e->rethrow($sNewMsg);                   # no format rule
2158
2159
2160 Propagates the exception using the method (C<PROPAGATE>) as would
2161 be called were one to use Perl's native 'rethrow' syntax,
2162 C<$@=$e; die>.
2163
2164 The first form with no arguments simply rethrows the exception.
2165 The remain formats let one override property values and/or update
2166 the message. The argument list is the same as for C<new> except
2167 that exceptions with no or object level format strings may have
2168 an undefined message.
2169
2170 For class format exceptions, the message will automatically be
2171 updated if any of the properties used to construct it have changed.
2172
2173 For exception classes with no formatting, property and message
2174 changes are independent of each other. If C<$sMsg> is set to C<undef>
2175 the properties will be changed and the message will be left alone.
2176 If C<$sMsg> is provided, but no override properties are provided,
2177 the message will change but the properties will be left untouched.
2178
2179 =head3 C<_p_getSubclassData>
2180
2181 Method for internal use by custom subclasses. This method retrieves
2182 the data hash reserved for use by custom methods.
2183
2184
2185 =head1 SEE ALSO
2186
2187 =head2 Canned test modules
2188
2189 Test modules for making sure your code generates the right
2190 exceptions.  They work with any OOP solution, even C<Exception::Lite>
2191
2192 * L<Test::Exception|Test::Exception>  - works with any OOP solution
2193
2194 * L<Test::Exception::LessClever|Test::Exception::LessClever> - works
2195   with any OOP solution
2196
2197 =head2 Alternate OOP solutions
2198
2199 =head3 L<Exception::Class|Exception::Class>
2200
2201 This module has a fair number of non-core modules. There are several
2202 extension modules. Most are adapter classes that convert exceptions
2203 produced by popular CPAN modules into Exception::Class modules:
2204
2205 * L<Exception::Class::Nested|Exception::Class::Nested> - changes
2206   the syntax for declaring exceptions.
2207
2208 * L<MooseX::Error::Exception::Class|MooseX::Error::Exception::Class>
2209   - converts Moose exceptions to
2210   C<Exception::Class> instances.
2211
2212 * L<HTTP::Exception|HTTP::Exception>  - wrapper around HTTP exceptions
2213
2214 * L<Mail::Log::Exceptions|Mail::Log::Exceptions> - wrapper around
2215   Mail::Log exceptions
2216
2217 * L<Exception::Class::DBI|Exception::Class::DBI> - wrapper around
2218   DBI exceptions
2219
2220 * L<Error::Exception|Error::Exception> - prints out exception
2221   properties as part of exception stringification.
2222
2223 It takes a heavy approach to OOP, requiring all properties to be
2224 predeclared.  It also stores a lot of information about an exception,
2225 not all of which is likely to be important to the average user, e.g.
2226 pid, uid, guid and even the entire stack trace.
2227
2228 There is no support for auto-generating messages based on
2229 properties.
2230
2231 For an extended discussion of C<Exception::Class>, see
2232 L<http://www.drdobbs.com/web-development/184416129>.
2233
2234 =head3 L<Exception::Base|Exception::Base>
2235
2236 A light weight version of L<Exception::Class|Exception::Class>.
2237 Uses only core modules but is fairly new and has no significant
2238 eco-system of extensions (yet).
2239 Like C<Exception::Class> properties must be explicitly declared and
2240 there is no support for autogenerating messages based on properties.
2241
2242
2243 =head3 L<Class::Throwable|Class::Throwable>
2244
2245 Another light weight version of L<Exception::Class|Exception::Class>.
2246 Unlike C<Exception::Class> you can control the amount of system
2247 state and stack trace information stored at the time an exception
2248 is generated.
2249
2250 =head2 Syntactic sugar solutions
2251
2252 Syntactical sugar solutions allow java like try/catch blocks to
2253 replace the more awkward C<die>, C<eval/do>, and C<$@=$e; die>
2254 pattern. Take care in chosing these methods as they sometimes
2255 use coding strategies known to cause problems:
2256
2257 =over
2258
2259 =item *
2260
2261 overriding signal handlers - possible interference with your own
2262 code or third party module use of those handlers.
2263
2264 =item *
2265
2266 source code filtering - can shift line numbers so that the reported
2267 line number and the actual line number may not be the same.
2268
2269 =item *
2270
2271 closures - there is a apparently a problem with nested closures
2272 causing memory leaks in some versions of Perl (pre 5.8.4). This
2273 has been since fixed since 5.8.4.
2274
2275 =back
2276
2277 Modules providing syntactic sugar include:
2278
2279 * L<Try::Catch|Try::Catch>
2280
2281 * L<Try::Tiny|Try::Tiny>
2282
2283 * C<Error|Error>
2284
2285 * L<Exception::Caught|Exception::Caught>
2286
2287 * L<Exception::SEH|Exception::SEH>
2288
2289 * C<Exception|Exception>
2290
2291 * L<Exception::Class::TryCatch|Exception::Class::TryCatch> - extension of L<Exception::Class|Exception::Class>
2292
2293 * L<Exception::Class::TCF|Exception::Class::TCF> - extension of L<Exception::Class|Exception::Class>
2294
2295
2296 =head1 EXPORTS
2297
2298 No subroutines are exported by default. See the start of the synopsis
2299 for optional exports.
2300
2301
2302 =head1 AUTHOR
2303
2304 Elizabeth Grace Frank-Backman
2305
2306 =head1 COPYRIGHT
2307
2308 Copyright (c) 2011 Elizabeth Grace Frank-Backman.
2309 All rights reserved.
2310
2311 =head1 LICENSE
2312
2313 This program is free software; you can redistribute it and/or
2314 modify it under the same terms as Perl itself.