This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Remove all mention of checkpods
[perl5.git] / lib / autodie / exception.pm
1 package autodie::exception;
2 use 5.008;
3 use strict;
4 use warnings;
5 use Carp qw(croak);
6
7 our $DEBUG = 0;
8
9 use overload
10     q{""} => "stringify"
11 ;
12
13 # Overload smart-match only if we're using 5.10
14
15 use if ($] >= 5.010), overload => '~~'  => "matches";
16
17 our $VERSION = '1.997';
18
19 my $PACKAGE = __PACKAGE__;  # Useful to have a scalar for hash keys.
20
21 =head1 NAME
22
23 autodie::exception - Exceptions from autodying functions.
24
25 =head1 SYNOPSIS
26
27     eval {
28         use autodie;
29
30         open(my $fh, '<', 'some_file.txt');
31
32         ...
33     };
34
35     if (my $E = $@) {
36         say "Ooops!  ",$E->caller," had problems: $@";
37     }
38
39
40 =head1 DESCRIPTION
41
42 When an L<autodie> enabled function fails, it generates an
43 C<autodie::exception> object.  This can be interrogated to
44 determine further information about the error that occurred.
45
46 This document is broken into two sections; those methods that
47 are most useful to the end-developer, and those methods for
48 anyone wishing to subclass or get very familiar with
49 C<autodie::exception>.
50
51 =head2 Common Methods
52
53 These methods are intended to be used in the everyday dealing
54 of exceptions.
55
56 The following assume that the error has been copied into
57 a separate scalar:
58
59     if ($E = $@) {
60         ...
61     }
62
63 This is not required, but is recommended in case any code
64 is called which may reset or alter C<$@>.
65
66 =cut
67
68 =head3 args
69
70     my $array_ref = $E->args;
71
72 Provides a reference to the arguments passed to the subroutine
73 that died.
74
75 =cut
76
77 sub args        { return $_[0]->{$PACKAGE}{args}; }
78
79 =head3 function
80
81     my $sub = $E->function;
82
83 The subroutine (including package) that threw the exception.
84
85 =cut
86
87 sub function   { return $_[0]->{$PACKAGE}{function};  }
88
89 =head3 file
90
91     my $file = $E->file;
92
93 The file in which the error occurred (eg, C<myscript.pl> or
94 C<MyTest.pm>).
95
96 =cut
97
98 sub file        { return $_[0]->{$PACKAGE}{file};  }
99
100 =head3 package
101
102     my $package = $E->package;
103
104 The package from which the exceptional subroutine was called.
105
106 =cut
107
108 sub package     { return $_[0]->{$PACKAGE}{package}; }
109
110 =head3 caller
111
112     my $caller = $E->caller;
113
114 The subroutine that I<called> the exceptional code.
115
116 =cut
117
118 sub caller      { return $_[0]->{$PACKAGE}{caller};  }
119
120 =head3 line
121
122     my $line = $E->line;
123
124 The line in C<< $E->file >> where the exceptional code was called.
125
126 =cut
127
128 sub line        { return $_[0]->{$PACKAGE}{line};  }
129
130 =head3 errno
131
132     my $errno = $E->errno;
133
134 The value of C<$!> at the time when the exception occurred.
135
136 B<NOTE>: This method will leave the main C<autodie::exception> class
137 and become part of a role in the future.  You should only call
138 C<errno> for exceptions where C<$!> would reasonably have been
139 set on failure.
140
141 =cut
142
143 # TODO: Make errno part of a role.  It doesn't make sense for
144 # everything.
145
146 sub errno       { return $_[0]->{$PACKAGE}{errno}; }
147
148 =head3 matches
149
150     if ( $e->matches('open') ) { ... }
151
152     if ( $e ~~ 'open' ) { ... }
153
154 C<matches> is used to determine whether a
155 given exception matches a particular role.  On Perl 5.10,
156 using smart-match (C<~~>) with an C<autodie::exception> object
157 will use C<matches> underneath.
158
159 An exception is considered to match a string if:
160
161 =over 4
162
163 =item *
164
165 For a string not starting with a colon, the string exactly matches the
166 package and subroutine that threw the exception.  For example,
167 C<MyModule::log>.  If the string does not contain a package name,
168 C<CORE::> is assumed.
169
170 =item *
171
172 For a string that does start with a colon, if the subroutine
173 throwing the exception I<does> that behaviour.  For example, the
174 C<CORE::open> subroutine does C<:file>, C<:io> and C<:all>.
175
176 See L<autodie/CATEGORIES> for futher information.
177
178 =back
179
180 =cut
181
182 {
183     my (%cache);
184
185     sub matches {
186         my ($this, $that) = @_;
187
188         # XXX - Handle references
189         croak "UNIMPLEMENTED" if ref $that;
190
191         my $sub = $this->function;
192
193         if ($DEBUG) {
194             my $sub2 = $this->function;
195             warn "Smart-matching $that against $sub / $sub2\n";
196         }
197
198         # Direct subname match.
199         return 1 if $that eq $sub;
200         return 1 if $that !~ /:/ and "CORE::$that" eq $sub;
201         return 0 if $that !~ /^:/;
202
203         # Cached match / check tags.
204         require Fatal;
205
206         if (exists $cache{$sub}{$that}) {
207             return $cache{$sub}{$that};
208         }
209
210         # This rather awful looking line checks to see if our sub is in the
211         # list of expanded tags, caches it, and returns the result.
212
213         return $cache{$sub}{$that} = grep { $_ eq $sub } @{ $this->_expand_tag($that) };
214     }
215 }
216
217 # This exists primarily so that child classes can override or
218 # augment it if they wish.
219
220 sub _expand_tag {
221     my ($this, @args) = @_;
222
223     return Fatal->_expand_tag(@args);
224 }
225
226 =head2 Advanced methods
227
228 The following methods, while usable from anywhere, are primarily
229 intended for developers wishing to subclass C<autodie::exception>,
230 write code that registers custom error messages, or otherwise
231 work closely with the C<autodie::exception> model.
232
233 =cut
234
235 # The table below records customer formatters.
236 # TODO - Should this be a package var instead?
237 # TODO - Should these be in a completely different file, or
238 #        perhaps loaded on demand?  Most formatters will never
239 #        get used in most programs.
240
241 my %formatter_of = (
242     'CORE::close'   => \&_format_close,
243     'CORE::open'    => \&_format_open,
244     'CORE::dbmopen' => \&_format_dbmopen,
245     'CORE::flock'   => \&_format_flock,
246 );
247
248 # TODO: Our tests only check LOCK_EX | LOCK_NB is properly
249 # formatted.  Try other combinations and ensure they work
250 # correctly.
251
252 sub _format_flock {
253     my ($this) = @_;
254
255     require Fcntl;
256
257     my $filehandle = $this->args->[0];
258     my $raw_mode   = $this->args->[1];
259
260     my $mode_type;
261     my $lock_unlock;
262
263     if ($raw_mode & Fcntl::LOCK_EX() ) {
264         $lock_unlock = "lock";
265         $mode_type = "for exclusive access";
266     }
267     elsif ($raw_mode & Fcntl::LOCK_SH() ) {
268         $lock_unlock = "lock";
269         $mode_type = "for shared access";
270     }
271     elsif ($raw_mode & Fcntl::LOCK_UN() ) {
272         $lock_unlock = "unlock";
273         $mode_type = "";
274     }
275     else {
276         # I've got no idea what they're trying to do.
277         $lock_unlock = "lock";
278         $mode_type = "with mode $raw_mode";
279     }
280
281     my $cooked_filehandle;
282
283     if ($filehandle and not ref $filehandle) {
284
285         # A package filehandle with a name!
286
287         $cooked_filehandle = " $filehandle";
288     }
289     else {
290         # Otherwise we have a scalar filehandle.
291
292         $cooked_filehandle = '';
293
294     }
295
296     local $! = $this->errno;
297
298     return "Can't $lock_unlock filehandle$cooked_filehandle $mode_type: $!";
299
300 }
301
302 # Default formatter for CORE::dbmopen
303 sub _format_dbmopen {
304     my ($this) = @_;
305     my @args   = @{$this->args};
306
307     # TODO: Presently, $args flattens out the (usually empty) hash
308     # which is passed as the first argument to dbmopen.  This is
309     # a bug in our args handling code (taking a reference to it would
310     # be better), but for the moment we'll just examine the end of
311     # our arguments list for message formatting.
312
313     my $mode = $args[-1];
314     my $file = $args[-2];
315
316     # If we have a mask, then display it in octal, not decimal.
317     # We don't do this if it already looks octalish, or doesn't
318     # look like a number.
319
320     if ($mode =~ /^[^\D0]\d+$/) {
321         $mode = sprintf("0%lo", $mode);
322     };
323
324     local $! = $this->errno;
325
326     return "Can't dbmopen(%hash, '$file', $mode): '$!'";
327 }
328
329 # Default formatter for CORE::close
330
331 sub _format_close {
332     my ($this) = @_;
333     my $close_arg = $this->args->[0];
334
335     local $! = $this->errno;
336
337     # If we've got an old-style filehandle, mention it.
338     if ($close_arg and not ref $close_arg) {
339         return "Can't close filehandle '$close_arg': '$!'";
340     }
341
342     # TODO - This will probably produce an ugly error.  Test and fix.
343     return "Can't close($close_arg) filehandle: '$!'";
344
345 }
346
347 # Default formatter for CORE::open
348
349 use constant _FORMAT_OPEN => "Can't open '%s' for %s: '%s'";
350
351 sub _format_open_with_mode {
352     my ($this, $mode, $file, $error) = @_;
353
354     my $wordy_mode;
355
356     if    ($mode eq '<')  { $wordy_mode = 'reading';   }
357     elsif ($mode eq '>')  { $wordy_mode = 'writing';   }
358     elsif ($mode eq '>>') { $wordy_mode = 'appending'; }
359
360     return sprintf _FORMAT_OPEN, $file, $wordy_mode, $error if $wordy_mode;
361
362     Carp::confess("Internal autodie::exception error: Don't know how to format mode '$mode'.");
363
364 }
365
366 sub _format_open {
367     my ($this) = @_;
368
369     my @open_args = @{$this->args};
370
371     # Use the default formatter for single-arg and many-arg open
372     if (@open_args <= 1 or @open_args >= 4) {
373         return $this->format_default;
374     }
375
376     # For two arg open, we have to extract the mode
377     if (@open_args == 2) {
378         my ($fh, $file) = @open_args;
379
380         if (ref($fh) eq "GLOB") {
381             $fh = '$fh';
382         }
383
384         my ($mode) = $file =~ m{
385             ^\s*                # Spaces before mode
386             (
387                 (?>             # Non-backtracking subexp.
388                     <           # Reading
389                     |>>?        # Writing/appending
390                 )
391             )
392             [^&]                # Not an ampersand (which means a dup)
393         }x;
394
395         # Have a funny mode?  Use the default format.
396         return $this->format_default if not defined $mode;
397
398         # Localising $! means perl make make it a pretty error for us.
399         local $! = $this->errno;
400
401         return $this->_format_open_with_mode($mode, $file, $!);
402     }
403
404     # Here we must be using three arg open.
405
406     my $file = $open_args[2];
407
408     local $! = $this->errno;
409
410     my $mode = $open_args[1];
411
412     local $@;
413
414     my $msg = eval { $this->_format_open_with_mode($mode, $file, $!); };
415
416     return $msg if $msg;
417
418     # Default message (for pipes and odd things)
419
420     return "Can't open '$file' with mode '$open_args[1]': '$!'";
421 }
422
423 =head3 register
424
425     autodie::exception->register( 'CORE::open' => \&mysub );
426
427 The C<register> method allows for the registration of a message
428 handler for a given subroutine.  The full subroutine name including
429 the package should be used.
430
431 Registered message handlers will receive the C<autodie::exception>
432 object as the first parameter.
433
434 =cut
435
436 sub register {
437     my ($class, $symbol, $handler) = @_;
438
439     croak "Incorrect call to autodie::register" if @_ != 3;
440
441     $formatter_of{$symbol} = $handler;
442
443 }
444
445 =head3 add_file_and_line
446
447     say "Problem occurred",$@->add_file_and_line;
448
449 Returns the string C< at %s line %d>, where C<%s> is replaced with
450 the filename, and C<%d> is replaced with the line number.
451
452 Primarily intended for use by format handlers.
453
454 =cut
455
456 # Simply produces the file and line number; intended to be added
457 # to the end of error messages.
458
459 sub add_file_and_line {
460     my ($this) = @_;
461
462     return sprintf(" at %s line %d\n", $this->file, $this->line);
463 }
464
465 =head3 stringify
466
467     say "The error was: ",$@->stringify;
468
469 Formats the error as a human readable string.  Usually there's no
470 reason to call this directly, as it is used automatically if an
471 C<autodie::exception> object is ever used as a string.
472
473 Child classes can override this method to change how they're
474 stringified.
475
476 =cut
477
478 sub stringify {
479     my ($this) = @_;
480
481     my $call        =  $this->function;
482
483     if ($DEBUG) {
484         my $dying_pkg   = $this->package;
485         my $sub   = $this->function;
486         my $caller = $this->caller;
487         warn "Stringifing exception for $dying_pkg :: $sub / $caller / $call\n";
488     }
489
490     # TODO - This isn't using inheritance.  Should it?
491     if ( my $sub = $formatter_of{$call} ) {
492         return $sub->($this) . $this->add_file_and_line;
493     }
494
495     return $this->format_default;
496
497 }
498
499 =head3 format_default
500
501     my $error_string = $E->format_default;
502
503 This produces the default error string for the given exception,
504 I<without using any registered message handlers>.  It is primarily
505 intended to be called from a message handler when they have
506 been passed an exception they don't want to format.
507
508 Child classes can override this method to change how default
509 messages are formatted.
510
511 =cut
512
513 # TODO: This produces ugly errors.  Is there any way we can
514 # dig around to find the actual variable names?  I know perl 5.10
515 # does some dark and terrible magicks to find them for undef warnings.
516
517 sub format_default {
518     my ($this) = @_;
519
520     my $call        =  $this->function;
521
522     local $! = $this->errno;
523
524     # TODO: This is probably a good idea for CORE, is it
525     # a good idea for other subs?
526
527     # Trim package name off dying sub for error messages.
528     $call =~ s/.*:://;
529
530     # Walk through all our arguments, and...
531     #
532     #   * Replace undef with the word 'undef'
533     #   * Replace globs with the string '$fh'
534     #   * Quote all other args.
535
536     my @args = @{ $this->args() };
537
538     foreach my $arg (@args) {
539        if    (not defined($arg))   { $arg = 'undef' }
540        elsif (ref($arg) eq "GLOB") { $arg = '$fh'   }
541        else                        { $arg = qq{'$arg'} }
542     }
543
544     # Format our beautiful error.
545
546     return "Can't $call(".  join(q{, }, @args) . "): $!" .
547         $this->add_file_and_line;
548
549     # TODO - Handle user-defined errors from hash.
550
551     # TODO - Handle default error messages.
552
553 }
554
555 =head3 new
556
557     my $error = autodie::exception->new(
558         args => \@_,
559         function => "CORE::open",
560         errno => $!,
561     );
562
563
564 Creates a new C<autodie::exception> object.  Normally called
565 directly from an autodying function.  The C<function> argument
566 is required, its the function we were trying to call that
567 generated the exception.  The C<args> parameter is optional.
568
569 The C<errno> value is optional.  In versions of C<autodie::exception>
570 1.99 and earlier the code would try to automatically use the
571 current value of C<$!>, but this was unreliable and is no longer
572 supported.
573
574 Atrributes such as package, file, and caller are determined
575 automatically, and cannot be specified.
576
577 =cut
578
579 sub new {
580     my ($class, @args) = @_;
581
582     my $this = {};
583
584     bless($this,$class);
585
586     # I'd love to use EVERY here, but it causes our code to die
587     # because it wants to stringify our objects before they're
588     # initialised, causing everything to explode.
589
590     $this->_init(@args);
591
592     return $this;
593 }
594
595 sub _init {
596
597     my ($this, %args) = @_;
598
599     # Capturing errno here is not necessarily reliable.
600     my $original_errno = $!;
601
602     our $init_called = 1;
603
604     my $class = ref $this;
605
606     # We're going to walk up our call stack, looking for the
607     # first thing that doesn't look like our exception
608     # code, autodie/Fatal, or some whacky eval.
609
610     my ($package, $file, $line, $sub);
611
612     my $depth = 0;
613
614     while (1) {
615         $depth++;
616
617         ($package, $file, $line, $sub) = CORE::caller($depth);
618
619         # Skip up the call stack until we find something outside
620         # of the Fatal/autodie/eval space.
621
622         next if $package->isa('Fatal');
623         next if $package->isa($class);
624         next if $package->isa(__PACKAGE__);
625         next if $file =~ /^\(eval\s\d+\)$/;
626
627         last;
628
629     }
630
631     $this->{$PACKAGE}{package} = $package;
632     $this->{$PACKAGE}{file}    = $file;
633     $this->{$PACKAGE}{line}    = $line;
634     $this->{$PACKAGE}{caller}  = $sub;
635     $this->{$PACKAGE}{package} = $package;
636
637     $this->{$PACKAGE}{errno}   = $args{errno} || 0;
638
639     $this->{$PACKAGE}{args}    = $args{args} || [];
640     $this->{$PACKAGE}{function}= $args{function} or
641               croak("$class->new() called without function arg");
642
643     return $this;
644
645 }
646
647 1;
648
649 __END__
650
651 =head1 SEE ALSO
652
653 L<autodie>, L<autodie::exception::system>
654
655 =head1 LICENSE
656
657 Copyright (C)2008 Paul Fenwick
658
659 This is free software.  You may modify and/or redistribute this
660 code under the same terms as Perl 5.10 itself, or, at your option,
661 any later version of Perl 5.
662
663 =head1 AUTHOR
664
665 Paul Fenwick E<lt>pjf@perltraining.com.auE<gt>