root/lib/Error.pm

Revision 89, 23.6 kB (checked in by cholt, 1 year ago)

error

Line 
1 # Error.pm
2 #
3 # Copyright (c) 1997-8 Graham Barr <gbarr@ti.com>. All rights reserved.
4 # This program is free software; you can redistribute it and/or
5 # modify it under the same terms as Perl itself.
6 #
7 # Based on my original Error.pm, and Exceptions.pm by Peter Seibel
8 # <peter@weblogic.com> and adapted by Jesse Glick <jglick@sig.bsh.com>.
9 #
10 # but modified ***significantly***
11
12 package Error;
13
14 use strict;
15 use vars qw($VERSION);
16 use 5.004;
17
18 $VERSION = "0.17015";
19
20 use overload (
21         '""'       =>   'stringify',
22         '0+'       =>   'value',
23         'bool'     =>   sub { return 1; },
24         'fallback' =>   1
25 );
26
27 $Error::Depth = 0;      # Depth to pass to caller()
28 $Error::Debug = 0;      # Generate verbose stack traces
29 @Error::STACK = ();     # Clause stack for try
30 $Error::THROWN = undef; # last error thrown, a workaround until die $ref works
31
32 my $LAST;               # Last error created
33 my %ERROR;              # Last error associated with package
34
35 sub _throw_Error_Simple
36 {
37     my $args = shift;
38     return Error::Simple->new($args->{'text'});
39 }
40
41 $Error::ObjectifyCallback = \&_throw_Error_Simple;
42
43
44 # Exported subs are defined in Error::subs
45
46 use Scalar::Util ();
47
48 sub import {
49     shift;
50     my @tags = @_;
51     local $Exporter::ExportLevel = $Exporter::ExportLevel + 1;
52    
53     @tags = grep {
54        if( $_ eq ':warndie' ) {
55           Error::WarnDie->import();
56           0;
57        }
58        else {
59           1;
60        }
61     } @tags;
62
63     Error::subs->import(@tags);
64 }
65
66 # I really want to use last for the name of this method, but it is a keyword
67 # which prevent the syntax  last Error
68
69 sub prior {
70     shift; # ignore
71
72     return $LAST unless @_;
73
74     my $pkg = shift;
75     return exists $ERROR{$pkg} ? $ERROR{$pkg} : undef
76         unless ref($pkg);
77
78     my $obj = $pkg;
79     my $err = undef;
80     if($obj->isa('HASH')) {
81         $err = $obj->{'__Error__'}
82             if exists $obj->{'__Error__'};
83     }
84     elsif($obj->isa('GLOB')) {
85         $err = ${*$obj}{'__Error__'}
86             if exists ${*$obj}{'__Error__'};
87     }
88
89     $err;
90 }
91
92 sub flush {
93     shift; #ignore
94     
95     unless (@_) {
96        $LAST = undef;
97        return;
98     }
99    
100     my $pkg = shift;
101     return unless ref($pkg);
102    
103     undef $ERROR{$pkg} if defined $ERROR{$pkg};
104 }
105
106 # Return as much information as possible about where the error
107 # happened. The -stacktrace element only exists if $Error::DEBUG
108 # was set when the error was created
109
110 sub stacktrace {
111     my $self = shift;
112
113     return $self->{'-stacktrace'}
114         if exists $self->{'-stacktrace'};
115
116     my $text = exists $self->{'-text'} ? $self->{'-text'} : "Died";
117
118     $text .= sprintf(" at %s line %d.\n", $self->file, $self->line)
119         unless($text =~ /\n$/s);
120
121     $text;
122 }
123
124
125 sub associate {
126     my $err = shift;
127     my $obj = shift;
128
129     return unless ref($obj);
130
131     if($obj->isa('HASH')) {
132         $obj->{'__Error__'} = $err;
133     }
134     elsif($obj->isa('GLOB')) {
135         ${*$obj}{'__Error__'} = $err;
136     }
137     $obj = ref($obj);
138     $ERROR{ ref($obj) } = $err;
139
140     return;
141 }
142
143
144 sub new {
145     my $self = shift;
146     my($pkg,$file,$line) = caller($Error::Depth);
147
148     my $err = bless {
149         '-package' => $pkg,
150         '-file'    => $file,
151         '-line'    => $line,
152         @_
153     }, $self;
154
155     $err->associate($err->{'-object'})
156         if(exists $err->{'-object'});
157
158     # To always create a stacktrace would be very inefficient, so
159     # we only do it if $Error::Debug is set
160
161     if($Error::Debug) {
162         require Carp;
163         local $Carp::CarpLevel = $Error::Depth;
164         my $text = defined($err->{'-text'}) ? $err->{'-text'} : "Error";
165         my $trace = Carp::longmess($text);
166         # Remove try calls from the trace
167         $trace =~ s/(\n\s+\S+__ANON__[^\n]+)?\n\s+eval[^\n]+\n\s+Error::subs::try[^\n]+(?=\n)//sog;
168         $trace =~ s/(\n\s+\S+__ANON__[^\n]+)?\n\s+eval[^\n]+\n\s+Error::subs::run_clauses[^\n]+\n\s+Error::subs::try[^\n]+(?=\n)//sog;
169         $err->{'-stacktrace'} = $trace
170     }
171
172     $@ = $LAST = $ERROR{$pkg} = $err;
173 }
174
175 # Throw an error. this contains some very gory code.
176
177 sub throw {
178     my $self = shift;
179     local $Error::Depth = $Error::Depth + 1;
180
181     # if we are not rethrow-ing then create the object to throw
182     $self = $self->new(@_) unless ref($self);
183    
184     die $Error::THROWN = $self;
185 }
186
187 # syntactic sugar for
188 #
189 #    die with Error( ... );
190
191 sub with {
192     my $self = shift;
193     local $Error::Depth = $Error::Depth + 1;
194
195     $self->new(@_);
196 }
197
198 # syntactic sugar for
199 #
200 #    record Error( ... ) and return;
201
202 sub record {
203     my $self = shift;
204     local $Error::Depth = $Error::Depth + 1;
205
206     $self->new(@_);
207 }
208
209 # catch clause for
210 #
211 # try { ... } catch CLASS with { ... }
212
213 sub catch {
214     my $pkg = shift;
215     my $code = shift;
216     my $clauses = shift || {};
217     my $catch = $clauses->{'catch'} ||= [];
218
219     unshift @$catch,  $pkg, $code;
220
221     $clauses;
222 }
223
224 # Object query methods
225
226 sub object {
227     my $self = shift;
228     exists $self->{'-object'} ? $self->{'-object'} : undef;
229 }
230
231 sub file {
232     my $self = shift;
233     exists $self->{'-file'} ? $self->{'-file'} : undef;
234 }
235
236 sub line {
237     my $self = shift;
238     exists $self->{'-line'} ? $self->{'-line'} : undef;
239 }
240
241 sub text {
242     my $self = shift;
243     exists $self->{'-text'} ? $self->{'-text'} : undef;
244 }
245
246 # overload methods
247
248 sub stringify {
249     my $self = shift;
250     defined $self->{'-text'} ? $self->{'-text'} : "Died";
251 }
252
253 sub value {
254     my $self = shift;
255     exists $self->{'-value'} ? $self->{'-value'} : undef;
256 }
257
258 package Error::Simple;
259
260 @Error::Simple::ISA = qw(Error);
261
262 sub new {
263     my $self  = shift;
264     my $text  = "" . shift;
265     my $value = shift;
266     my(@args) = ();
267
268     local $Error::Depth = $Error::Depth + 1;
269
270     @args = ( -file => $1, -line => $2)
271         if($text =~ s/\s+at\s+(\S+)\s+line\s+(\d+)(?:,\s*<[^>]*>\s+line\s+\d+)?\.?\n?$//s);
272     push(@args, '-value', 0 + $value)
273         if defined($value);
274
275     $self->SUPER::new(-text => $text, @args);
276 }
277
278 sub stringify {
279     my $self = shift;
280     my $text = $self->SUPER::stringify;
281     $text .= sprintf(" at %s line %d.\n", $self->file, $self->line)
282         unless($text =~ /\n$/s);
283     $text;
284 }
285
286 ##########################################################################
287 ##########################################################################
288
289 # Inspired by code from Jesse Glick <jglick@sig.bsh.com> and
290 # Peter Seibel <peter@weblogic.com>
291
292 package Error::subs;
293
294 use Exporter ();
295 use vars qw(@EXPORT_OK @ISA %EXPORT_TAGS);
296
297 @EXPORT_OK   = qw(try with finally except otherwise);
298 %EXPORT_TAGS = (try => \@EXPORT_OK);
299
300 @ISA = qw(Exporter);
301
302 sub run_clauses ($$$\@) {
303     my($clauses,$err,$wantarray,$result) = @_;
304     my $code = undef;
305
306     $err = $Error::ObjectifyCallback->({'text' =>$err}) unless ref($err);
307
308     CATCH: {
309
310         # catch
311         my $catch;
312         if(defined($catch = $clauses->{'catch'})) {
313             my $i = 0;
314
315             CATCHLOOP:
316             for( ; $i < @$catch ; $i += 2) {
317                 my $pkg = $catch->[$i];
318                 unless(defined $pkg) {
319                     #except
320                     splice(@$catch,$i,2,$catch->[$i+1]->($err));
321                     $i -= 2;
322                     next CATCHLOOP;
323                 }
324                 elsif(Scalar::Util::blessed($err) && $err->isa($pkg)) {
325                     $code = $catch->[$i+1];
326                     while(1) {
327                         my $more = 0;
328                         local($Error::THROWN, $@);
329                         my $ok = eval {
330                             $@ = $err;
331                             if($wantarray) {
332                                 @{$result} = $code->($err,\$more);
333                             }
334                             elsif(defined($wantarray)) {
335                                 @{$result} = ();
336                                 $result->[0] = $code->($err,\$more);
337                             }
338                             else {
339                                 $code->($err,\$more);
340                             }
341                             1;
342                         };
343                         if( $ok ) {
344                             next CATCHLOOP if $more;
345                             undef $err;
346                         }
347                         else {
348                             $err = $@ || $Error::THROWN;
349                                 $err = $Error::ObjectifyCallback->({'text' =>$err})
350                                         unless ref($err);
351                         }
352                         last CATCH;
353                     };
354                 }
355             }
356         }
357
358         # otherwise
359         my $owise;
360         if(defined($owise = $clauses->{'otherwise'})) {
361             my $code = $clauses->{'otherwise'};
362             my $more = 0;
363         local($Error::THROWN, $@);
364             my $ok = eval {
365                 $@ = $err;
366                 if($wantarray) {
367                     @{$result} = $code->($err,\$more);
368                 }
369                 elsif(defined($wantarray)) {
370                     @{$result} = ();
371                     $result->[0] = $code->($err,\$more);
372                 }
373                 else {
374                     $code->($err,\$more);
375                 }
376                 1;
377             };
378             if( $ok ) {
379                 undef $err;
380             }
381             else {
382                 $err = $@ || $Error::THROWN;
383
384                 $err = $Error::ObjectifyCallback->({'text' =>$err})
385                         unless ref($err);
386             }
387         }
388     }
389     $err;
390 }
391
392 sub try (&;$) {
393     my $try = shift;
394     my $clauses = @_ ? shift : {};
395     my $ok = 0;
396     my $err = undef;
397     my @result = ();
398
399     unshift @Error::STACK, $clauses;
400
401     my $wantarray = wantarray();
402
403     do {
404         local $Error::THROWN = undef;
405         local $@ = undef;
406
407         $ok = eval {
408             if($wantarray) {
409                 @result = $try->();
410             }
411             elsif(defined $wantarray) {
412                 $result[0] = $try->();
413             }
414             else {
415                 $try->();
416             }
417             1;
418         };
419
420         $err = $@ || $Error::THROWN
421             unless $ok;
422     };
423
424     shift @Error::STACK;
425
426     $err = run_clauses($clauses,$err,wantarray,@result)
427     unless($ok);
428
429     $clauses->{'finally'}->()
430         if(defined($clauses->{'finally'}));
431
432     if (defined($err))
433     {
434         if (Scalar::Util::blessed($err) && $err->can('throw'))
435         {
436             throw $err;
437         }
438         else
439         {
440             die $err;
441         }
442     }
443
444     wantarray ? @result : $result[0];
445 }
446
447 # Each clause adds a sub to the list of clauses. The finally clause is
448 # always the last, and the otherwise clause is always added just before
449 # the finally clause.
450 #
451 # All clauses, except the finally clause, add a sub which takes one argument
452 # this argument will be the error being thrown. The sub will return a code ref
453 # if that clause can handle that error, otherwise undef is returned.
454 #
455 # The otherwise clause adds a sub which unconditionally returns the users
456 # code reference, this is why it is forced to be last.
457 #
458 # The catch clause is defined in Error.pm, as the syntax causes it to
459 # be called as a method
460
461 sub with (&;$) {
462     @_
463 }
464
465 sub finally (&) {
466     my $code = shift;
467     my $clauses = { 'finally' => $code };
468     $clauses;
469 }
470
471 # The except clause is a block which returns a hashref or a list of
472 # key-value pairs, where the keys are the classes and the values are subs.
473
474 sub except (&;$) {
475     my $code = shift;
476     my $clauses = shift || {};
477     my $catch = $clauses->{'catch'} ||= [];
478    
479     my $sub = sub {
480         my $ref;
481         my(@array) = $code->($_[0]);
482         if(@array == 1 && ref($array[0])) {
483             $ref = $array[0];
484             $ref = [ %$ref ]
485                 if(UNIVERSAL::isa($ref,'HASH'));
486         }
487         else {
488             $ref = \@array;
489         }
490         @$ref
491     };
492
493     unshift @{$catch}, undef, $sub;
494
495     $clauses;
496 }
497
498 sub otherwise (&;$) {
499     my $code = shift;
500     my $clauses = shift || {};
501
502     if(exists $clauses->{'otherwise'}) {
503         require Carp;
504         Carp::croak("Multiple otherwise clauses");
505     }
506
507     $clauses->{'otherwise'} = $code;
508
509     $clauses;
510 }
511
512 1;
513
514 package Error::WarnDie;
515
516 sub gen_callstack($)
517 {
518     my ( $start ) = @_;
519
520     require Carp;
521     local $Carp::CarpLevel = $start;
522     my $trace = Carp::longmess("");
523     # Remove try calls from the trace
524     $trace =~ s/(\n\s+\S+__ANON__[^\n]+)?\n\s+eval[^\n]+\n\s+Error::subs::try[^\n]+(?=\n)//sog;
525     $trace =~ s/(\n\s+\S+__ANON__[^\n]+)?\n\s+eval[^\n]+\n\s+Error::subs::run_clauses[^\n]+\n\s+Error::subs::try[^\n]+(?=\n)//sog;
526     my @callstack = split( m/\n/, $trace );
527     return @callstack;
528 }
529
530 my $old_DIE;
531 my $old_WARN;
532
533 sub DEATH
534 {
535     my ( $e ) = @_;
536
537     local $SIG{__DIE__} = $old_DIE if( defined $old_DIE );
538
539     die @_ if $^S;
540
541     my ( $etype, $message, $location, @callstack );
542     if ( ref($e) && $e->isa( "Error" ) ) {
543         $etype = "exception of type " . ref( $e );
544         $message = $e->text;
545         $location = $e->file . ":" . $e->line;
546         @callstack = split( m/\n/, $e->stacktrace );
547     }
548     else {
549         # Don't apply subsequent layer of message formatting
550         die $e if( $e =~ m/^\nUnhandled perl error caught at toplevel:\n\n/ );
551         $etype = "perl error";
552         my $stackdepth = 0;
553         while( caller( $stackdepth ) =~ m/^Error(?:$|::)/ ) {
554             $stackdepth++
555         }
556
557         @callstack = gen_callstack( $stackdepth + 1 );
558
559         $message = "$e";
560         chomp $message;
561
562         if ( $message =~ s/ at (.*?) line (\d+)\.$// ) {
563             $location = $1 . ":" . $2;
564         }
565         else {
566             my @caller = caller( $stackdepth );
567             $location = $caller[1] . ":" . $caller[2];
568         }
569     }
570
571     shift @callstack;
572     # Do it this way in case there are no elements; we don't print a spurious \n
573     my $callstack = join( "", map { "$_\n"} @callstack );
574
575     die "\nUnhandled $etype caught at toplevel:\n\n  $message\n\nThrown from: $location\n\nFull stack trace:\n\n$callstack\n";
576 }
577
578 sub TAXES
579 {
580     my ( $message ) = @_;
581
582     local $SIG{__WARN__} = $old_WARN if( defined $old_WARN );
583
584     $message =~ s/ at .*? line \d+\.$//;
585     chomp $message;
586
587     my @callstack = gen_callstack( 1 );
588     my $location = shift @callstack;
589
590     # $location already starts in a leading space
591     $message .= $location;
592
593     # Do it this way in case there are no elements; we don't print a spurious \n
594     my $callstack = join( "", map { "$_\n"} @callstack );
595
596     warn "$message:\n$callstack";
597 }
598
599 sub import
600 {
601     $old_DIE  = $SIG{__DIE__};
602     $old_WARN = $SIG{__WARN__};
603
604     $SIG{__DIE__}  = \&DEATH;
605     $SIG{__WARN__} = \&TAXES;
606 }
607
608 1;
609
610 __END__
611
612 =head1 NAME
613
614 Error - Error/exception handling in an OO-ish way
615
616 =head1 SYNOPSIS
617
618     use Error qw(:try);
619
620     throw Error::Simple( "A simple error");
621
622     sub xyz {
623         ...
624         record Error::Simple("A simple error")
625             and return;
626     }
627  
628     unlink($file) or throw Error::Simple("$file: $!",$!);
629
630     try {
631         do_some_stuff();
632         die "error!" if $condition;
633         throw Error::Simple "Oops!" if $other_condition;
634     }
635     catch Error::IO with {
636         my $E = shift;
637         print STDERR "File ", $E->{'-file'}, " had a problem\n";
638     }
639     except {
640         my $E = shift;
641         my $general_handler=sub {send_message $E->{-description}};
642         return {
643             UserException1 => $general_handler,
644             UserException2 => $general_handler
645         };
646     }
647     otherwise {
648         print STDERR "Well I don't know what to say\n";
649     }
650     finally {
651         close_the_garage_door_already(); # Should be reliable
652     }; # Don't forget the trailing ; or you might be surprised
653
654 =head1 DESCRIPTION
655
656 The C<Error> package provides two interfaces. Firstly C<Error> provides
657 a procedural interface to exception handling. Secondly C<Error> is a
658 base class for errors/exceptions that can either be thrown, for
659 subsequent catch, or can simply be recorded.
660
661 Errors in the class C<Error> should not be thrown directly, but the
662 user should throw errors from a sub-class of C<Error>.
663
664 =head1 PROCEDURAL INTERFACE
665
666 C<Error> exports subroutines to perform exception handling. These will
667 be exported if the C<:try> tag is used in the C<use> line.
668
669 =over 4
670
671 =item try BLOCK CLAUSES
672
673 C<try> is the main subroutine called by the user. All other subroutines
674 exported are clauses to the try subroutine.
675
676 The BLOCK will be evaluated and, if no error is throw, try will return
677 the result of the block.
678
679 C<CLAUSES> are the subroutines below, which describe what to do in the
680 event of an error being thrown within BLOCK.
681
682 =item catch CLASS with BLOCK
683
684 This clauses will cause all errors that satisfy C<$err-E<gt>isa(CLASS)>
685 to be caught and handled by evaluating C<BLOCK>.
686
687 C<BLOCK> will be passed two arguments. The first will be the error
688 being thrown. The second is a reference to a scalar variable. If this
689 variable is set by the catch block then, on return from the catch
690 block, try will continue processing as if the catch block was never
691 found. The error will also be available in C<$@>.
692
693 To propagate the error the catch block may call C<$err-E<gt>throw>
694
695 If the scalar reference by the second argument is not set, and the
696 error is not thrown. Then the current try block will return with the
697 result from the catch block.
698
699 =item except BLOCK
700
701 When C<try> is looking for a handler, if an except clause is found
702 C<BLOCK> is evaluated. The return value from this block should be a
703 HASHREF or a list of key-value pairs, where the keys are class names
704 and the values are CODE references for the handler of errors of that
705 type.
706
707 =item otherwise BLOCK
708
709 Catch any error by executing the code in C<BLOCK>
710
711 When evaluated C<BLOCK> will be passed one argument, which will be the
712 error being processed. The error will also be available in C<$@>.
713
714 Only one otherwise block may be specified per try block
715
716 =item finally BLOCK
717
718 Execute the code in C<BLOCK> either after the code in the try block has
719 successfully completed, or if the try block throws an error then
720 C<BLOCK> will be executed after the handler has completed.
721
722 If the handler throws an error then the error will be caught, the
723 finally block will be executed and the error will be re-thrown.
724
725 Only one finally block may be specified per try block
726
727 =back
728
729 =head1 CLASS INTERFACE
730
731 =head2 CONSTRUCTORS
732
733 The C<Error> object is implemented as a HASH. This HASH is initialized
734 with the arguments that are passed to it's constructor. The elements
735 that are used by, or are retrievable by the C<Error> class are listed
736 below, other classes may add to these.
737
738         -file
739         -line
740         -text
741         -value
742         -object
743
744 If C<-file> or C<-line> are not specified in the constructor arguments
745 then these will be initialized with the file name and line number where
746 the constructor was called from.
747
748 If the error is associated with an object then the object should be
749 passed as the C<-object> argument. This will allow the C<Error> package
750 to associate the error with the object.
751
752 The C<Error> package remembers the last error created, and also the
753 last error associated with a package. This could either be the last
754 error created by a sub in that package, or the last error which passed
755 an object blessed into that package as the C<-object> argument.
756
757 =over 4
758
759 =item Error->new()
760
761 See the Error::Simple documentation.
762
763 =item throw ( [ ARGS ] )
764
765 Create a new C<Error> object and throw an error, which will be caught
766 by a surrounding C<try> block, if there is one. Otherwise it will cause
767 the program to exit.
768
769 C<throw> may also be called on an existing error to re-throw it.
770
771 =item with ( [ ARGS ] )
772
773 Create a new C<Error> object and returns it. This is defined for
774 syntactic sugar, eg
775
776     die with Some::Error ( ... );
777
778 =item record ( [ ARGS ] )
779
780 Create a new C<Error> object and returns it. This is defined for
781 syntactic sugar, eg
782
783     record Some::Error ( ... )
784         and return;
785
786 =back
787
788 =head2 STATIC METHODS
789
790 =over 4
791
792 =item prior ( [ PACKAGE ] )
793
794 Return the last error created, or the last error associated with
795 C<PACKAGE>
796
797 =item flush ( [ PACKAGE ] )
798
799 Flush the last error created, or the last error associated with
800 C<PACKAGE>.It is necessary to clear the error stack before exiting the
801 package or uncaught errors generated using C<record> will be reported.
802
803      $Error->flush;
804
805 =cut
806
807 =back
808
809 =head2 OBJECT METHODS
810
811 =over 4
812
813 =item stacktrace
814
815 If the variable C<$Error::Debug> was non-zero when the error was
816 created, then C<stacktrace> returns a string created by calling
817 C<Carp::longmess>. If the variable was zero the C<stacktrace> returns
818 the text of the error appended with the filename and line number of
819 where the error was created, providing the text does not end with a
820 newline.
821
822 =item object
823
824 The object this error was associated with
825
826 =item file
827
828 The file where the constructor of this error was called from
829
830 =item line
831
832 The line where the constructor of this error was called from
833
834 =item text
835
836 The text of the error
837
838 =item $err->associate($obj)
839
840 Associates an error with an object to allow error propagation. I.e:
841
842     $ber->encode(...) or
843         return Error->prior($ber)->associate($ldap);
844
845 =back
846
847 =head2 OVERLOAD METHODS
848
849 =over 4
850
851 =item stringify
852
853 A method that converts the object into a string. This method may simply
854 return the same as the C<text> method, or it may append more
855 information. For example the file name and line number.
856
857 By default this method returns the C<-text> argument that was passed to
858 the constructor, or the string C<"Died"> if none was given.
859
860 =item value
861
862 A method that will return a value that can be associated with the
863 error. For example if an error was created due to the failure of a
864 system call, then this may return the numeric value of C<$!> at the
865 time.
866
867 By default this method returns the C<-value> argument that was passed
868 to the constructor.
869
870 =back
871
872 =head1 PRE-DEFINED ERROR CLASSES
873
874 =head2 Error::Simple
875
876 This class can be used to hold simple error strings and values. It's
877 constructor takes two arguments. The first is a text value, the second
878 is a numeric value. These values are what will be returned by the
879 overload methods.
880
881 If the text value ends with C<at file line 1> as $@ strings do, then
882 this infomation will be used to set the C<-file> and C<-line> arguments
883 of the error object.
884
885 This class is used internally if an eval'd block die's with an error
886 that is a plain string. (Unless C<$Error::ObjectifyCallback> is modified)
887
888
889 =head1 $Error::ObjectifyCallback
890
891 This variable holds a reference to a subroutine that converts errors that
892 are plain strings to objects. It is used by Error.pm to convert textual
893 errors to objects, and can be overrided by the user.
894
895 It accepts a single argument which is a hash reference to named parameters.
896 Currently the only named parameter passed is C<'text'> which is the text
897 of the error, but others may be available in the future.
898
899 For example the following code will cause Error.pm to throw objects of the
900 class MyError::Bar by default:
901
902     sub throw_MyError_Bar
903     {
904         my $args = shift;
905         my $err = MyError::Bar->new();
906         $err->{'MyBarText'} = $args->{'text'};
907         return $err;
908     }
909
910     {
911         local $Error::ObjectifyCallback = \&throw_MyError_Bar;
912
913         # Error handling here.
914     }
915
916 =cut
917
918 =head1 MESSAGE HANDLERS
919
920 C<Error> also provides handlers to extend the output of the C<warn()> perl
921 function, and to handle the printing of a thrown C<Error> that is not caught
922 or otherwise handled. These are not installed by default, but are requested
923 using the C<:warndie> tag in the C<use> line.
924
925  use Error qw( :warndie );
926
927 These new error handlers are installed in C<$SIG{__WARN__}> and
928 C<$SIG{__DIE__}>. If these handlers are already defined when the tag is
929 imported, the old values are stored, and used during the new code. Thus, to
930 arrange for custom handling of warnings and errors, you will need to perform
931 something like the following:
932
933  BEGIN {
934    $SIG{__WARN__} = sub {
935      print STDERR "My special warning handler: $_[0]"
936    };
937  }
938
939  use Error qw( :warndie );
940
941 Note that setting C<$SIG{__WARN__}> after the C<:warndie> tag has been
942 imported will overwrite the handler that C<Error> provides. If this cannot be
943 avoided, then the tag can be explicitly C<import>ed later
944
945  use Error;
946
947  $SIG{__WARN__} = ...;
948
949  import Error qw( :warndie );
950
951 =head2 EXAMPLE
952
953 The C<__DIE__> handler turns messages such as
954
955  Can't call method "foo" on an undefined value at examples/warndie.pl line 16.
956
957 into
958
959  Unhandled perl error caught at toplevel:
960
961    Can't call method "foo" on an undefined value
962
963  Thrown from: examples/warndie.pl:16
964
965  Full stack trace:
966
967          main::inner('undef') called at examples/warndie.pl line 20
968          main::outer('undef') called at examples/warndie.pl line 23
969
970 =cut
971
972 =head1 SEE ALSO
973
974 See L<Exception::Class> for a different module providing Object-Oriented
975 exception handling, along with a convenient syntax for declaring hierarchies
976 for them. It doesn't provide Error's syntactic sugar of C<try { ... }>,
977 C<catch { ... }>, etc. which may be a good thing or a bad thing based
978 on what you want. (Because Error's syntactic sugar tends to break.)
979
980 L<Error::Exception> aims to combine L<Error> and L<Exception::Class>
981 "with correct stringification".
982
983 =head1 KNOWN BUGS
984
985 None, but that does not mean there are not any.
986
987 =head1 AUTHORS
988
989 Graham Barr <gbarr@pobox.com>
990
991 The code that inspired me to write this was originally written by
992 Peter Seibel <peter@weblogic.com> and adapted by Jesse Glick
993 <jglick@sig.bsh.com>.
994
995 C<:warndie> handlers added by Paul Evans <leonerd@leonerd.org.uk>
996
997 =head1 MAINTAINER
998
999 Shlomi Fish <shlomif@iglu.org.il>
1000
1001 =head1 PAST MAINTAINERS
1002
1003 Arun Kumar U <u_arunkumar@yahoo.com>
1004
1005 =head1 COPYRIGHT
1006
1007 Copyright (c) 1997-8  Graham Barr. All rights reserved.
1008 This program is free software; you can redistribute it and/or modify it
1009 under the same terms as Perl itself.
1010
1011 =cut
1012
Note: See TracBrowser for help on using the browser.