Commit | Line | Data |
0b09a93a |
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 | |
9b657a62 |
17 | our $VERSION = '2.00'; |
0b09a93a |
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 | |
9b657a62 |
188 | # TODO - Handle references |
0b09a93a |
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 | |
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 |
9b657a62 |
647 | # where we were called from the top level of a program. |
db4e6d09 |
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 | |
669 | 1; |
670 | |
671 | __END__ |
672 | |
673 | =head1 SEE ALSO |
674 | |
675 | L<autodie>, L<autodie::exception::system> |
676 | |
677 | =head1 LICENSE |
678 | |
679 | Copyright (C)2008 Paul Fenwick |
680 | |
681 | This is free software. You may modify and/or redistribute this |
682 | code under the same terms as Perl 5.10 itself, or, at your option, |
683 | any later version of Perl 5. |
684 | |
685 | =head1 AUTHOR |
686 | |
687 | Paul Fenwick E<lt>pjf@perltraining.com.auE<gt> |