Fixes for ext/compress
[p5sagit/p5-mst-13.2.git] / lib / autodie / exception.pm
CommitLineData
0b09a93a 1package autodie::exception;
2use 5.008;
3use strict;
4use warnings;
5use Carp qw(croak);
6
7our $DEBUG = 0;
8
9use overload
10 q{""} => "stringify"
11;
12
13# Overload smart-match only if we're using 5.10
14
15use if ($] >= 5.010), overload => '~~' => "matches";
16
db4e6d09 17our $VERSION = '1.999';
0b09a93a 18
19my $PACKAGE = __PACKAGE__; # Useful to have a scalar for hash keys.
20
21=head1 NAME
22
23autodie::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
42When an L<autodie> enabled function fails, it generates an
43C<autodie::exception> object. This can be interrogated to
44determine further information about the error that occurred.
45
46This document is broken into two sections; those methods that
47are most useful to the end-developer, and those methods for
48anyone wishing to subclass or get very familiar with
49C<autodie::exception>.
50
51=head2 Common Methods
52
53These methods are intended to be used in the everyday dealing
54of exceptions.
55
56The following assume that the error has been copied into
57a separate scalar:
58
59 if ($E = $@) {
60 ...
61 }
62
63This is not required, but is recommended in case any code
64is called which may reset or alter C<$@>.
65
66=cut
67
68=head3 args
69
70 my $array_ref = $E->args;
71
72Provides a reference to the arguments passed to the subroutine
73that died.
74
75=cut
76
77sub args { return $_[0]->{$PACKAGE}{args}; }
78
79=head3 function
80
81 my $sub = $E->function;
82
83The subroutine (including package) that threw the exception.
84
85=cut
86
87sub function { return $_[0]->{$PACKAGE}{function}; }
88
89=head3 file
90
91 my $file = $E->file;
92
93The file in which the error occurred (eg, C<myscript.pl> or
94C<MyTest.pm>).
95
96=cut
97
98sub file { return $_[0]->{$PACKAGE}{file}; }
99
100=head3 package
101
102 my $package = $E->package;
103
104The package from which the exceptional subroutine was called.
105
106=cut
107
108sub package { return $_[0]->{$PACKAGE}{package}; }
109
110=head3 caller
111
112 my $caller = $E->caller;
113
114The subroutine that I<called> the exceptional code.
115
116=cut
117
118sub caller { return $_[0]->{$PACKAGE}{caller}; }
119
120=head3 line
121
122 my $line = $E->line;
123
124The line in C<< $E->file >> where the exceptional code was called.
125
126=cut
127
128sub line { return $_[0]->{$PACKAGE}{line}; }
129
130=head3 errno
131
132 my $errno = $E->errno;
133
134The value of C<$!> at the time when the exception occurred.
135
136B<NOTE>: This method will leave the main C<autodie::exception> class
137and become part of a role in the future. You should only call
138C<errno> for exceptions where C<$!> would reasonably have been
139set on failure.
140
141=cut
142
143# TODO: Make errno part of a role. It doesn't make sense for
144# everything.
145
146sub errno { return $_[0]->{$PACKAGE}{errno}; }
147
148=head3 matches
149
150 if ( $e->matches('open') ) { ... }
151
152 if ( $e ~~ 'open' ) { ... }
153
154C<matches> is used to determine whether a
155given exception matches a particular role. On Perl 5.10,
156using smart-match (C<~~>) with an C<autodie::exception> object
157will use C<matches> underneath.
158
159An exception is considered to match a string if:
160
161=over 4
162
163=item *
164
165For a string not starting with a colon, the string exactly matches the
166package and subroutine that threw the exception. For example,
167C<MyModule::log>. If the string does not contain a package name,
168C<CORE::> is assumed.
169
170=item *
171
172For a string that does start with a colon, if the subroutine
173throwing the exception I<does> that behaviour. For example, the
174C<CORE::open> subroutine does C<:file>, C<:io> and C<:all>.
175
176See 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
220sub _expand_tag {
221 my ($this, @args) = @_;
222
223 return Fatal->_expand_tag(@args);
224}
225
226=head2 Advanced methods
227
228The following methods, while usable from anywhere, are primarily
229intended for developers wishing to subclass C<autodie::exception>,
230write code that registers custom error messages, or otherwise
231work 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
241my %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
252sub _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
303sub _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
331sub _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
349use constant _FORMAT_OPEN => "Can't open '%s' for %s: '%s'";
350
351sub _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
366sub _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
427The C<register> method allows for the registration of a message
428handler for a given subroutine. The full subroutine name including
429the package should be used.
430
431Registered message handlers will receive the C<autodie::exception>
432object as the first parameter.
433
434=cut
435
436sub 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
449Returns the string C< at %s line %d>, where C<%s> is replaced with
450the filename, and C<%d> is replaced with the line number.
451
452Primarily 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
459sub 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
469Formats the error as a human readable string. Usually there's no
470reason to call this directly, as it is used automatically if an
471C<autodie::exception> object is ever used as a string.
472
473Child classes can override this method to change how they're
474stringified.
475
476=cut
477
478sub 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
503This produces the default error string for the given exception,
504I<without using any registered message handlers>. It is primarily
505intended to be called from a message handler when they have
506been passed an exception they don't want to format.
507
508Child classes can override this method to change how default
509messages 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
517sub 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
564Creates a new C<autodie::exception> object. Normally called
565directly from an autodying function. The C<function> argument
566is required, its the function we were trying to call that
567generated the exception. The C<args> parameter is optional.
568
569The C<errno> value is optional. In versions of C<autodie::exception>
5701.99 and earlier the code would try to automatically use the
571current value of C<$!>, but this was unreliable and is no longer
572supported.
573
574Atrributes such as package, file, and caller are determined
575automatically, and cannot be specified.
576
577=cut
578
579sub 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
595sub _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
db4e6d09 631 # We now have everything correct, *except* for our subroutine
632 # name. If it's __ANON__ or (eval), then we need to keep on
633 # digging deeper into our stack to find the real name. However we
634 # don't update our other information, since that will be correct
635 # for our current exception.
636
637 my $first_guess_subroutine = $sub;
638
639 while (defined $sub and $sub =~ /^\(eval\)$|::__ANON__$/) {
640 $depth++;
641
642 $sub = (CORE::caller($depth))[3];
643 }
644
645 # If we end up falling out the bottom of our stack, then our
646 # __ANON__ guess is the best we can get. This includes situations
647 # where we were called from thetop level of a program.
648
649 if (not defined $sub) {
650 $sub = $first_guess_subroutine;
651 }
652
0b09a93a 653 $this->{$PACKAGE}{package} = $package;
654 $this->{$PACKAGE}{file} = $file;
655 $this->{$PACKAGE}{line} = $line;
656 $this->{$PACKAGE}{caller} = $sub;
657 $this->{$PACKAGE}{package} = $package;
658
659 $this->{$PACKAGE}{errno} = $args{errno} || 0;
660
661 $this->{$PACKAGE}{args} = $args{args} || [];
662 $this->{$PACKAGE}{function}= $args{function} or
663 croak("$class->new() called without function arg");
664
665 return $this;
666
667}
668
6691;
670
671__END__
672
673=head1 SEE ALSO
674
675L<autodie>, L<autodie::exception::system>
676
677=head1 LICENSE
678
679Copyright (C)2008 Paul Fenwick
680
681This is free software. You may modify and/or redistribute this
682code under the same terms as Perl 5.10 itself, or, at your option,
683any later version of Perl 5.
684
685=head1 AUTHOR
686
687Paul Fenwick E<lt>pjf@perltraining.com.auE<gt>