File Coverage

blib/lib/failures.pm
Criterion Covered Total %
statement 61 61 100.0
branch 16 16 100.0
condition 6 6 100.0
subroutine 14 14 100.0
pod n/a
total 97 97 100.0


line stmt bran cond sub pod time code
1 2     2   30461 use 5.008001;
  2         8  
  2         70  
2 2     2   11 use strict;
  2         4  
  2         50  
3 2     2   8 use warnings;
  2         4  
  2         109  
4              
5             package failures;
6             # ABSTRACT: Minimalist exception hierarchy generator
7             our $VERSION = '0.004'; # VERSION
8              
9             sub import {
10 2     2   12 no strict 'refs';
  2         4  
  2         547  
11 3     3   525 my ( $class, @failures ) = @_;
12 3         7 my $caller = caller;
13 3         7 my $is_custom = $class eq 'custom::failures';
14 3 100 100     20 if ( $is_custom && ref $failures[1] eq 'ARRAY' ) {
15 1         9 $caller = shift @failures;
16 1         2 @failures = @{ $failures[0] };
  1         4  
17             }
18 3         8 for my $f (@failures) {
19             # XXX should check $f for valid package name
20 5         9 my $custom = $caller;
21 5         6 my $default = 'failure';
22 5 100       14 push @{"$custom\::ISA"}, $default if $is_custom;
  2         22  
23 5         17 for my $p ( split /::/, $f ) {
24 9         8 push @{"$default\::$p\::ISA"}, $default;
  9         133  
25 9         25 $default .= "::$p";
26 9 100       2680 if ($is_custom) {
27 4         4 push @{"$custom\::$p\::ISA"}, $custom, $default;
  4         72  
28 4         75 $custom .= "::$p";
29             }
30             }
31             }
32             }
33              
34             package failure;
35              
36 2     2   2134 use Class::Tiny { msg => '', trace => '', payload => undef };
  2         6781  
  2         19  
37              
38 2     2   4962 use overload ( q{""} => \&as_string, fallback => 1 );
  2         2132  
  2         20  
39              
40             sub throw {
41 12     12   24920 my ( $class, $msg ) = @_;
42 12 100       50 my $m = ref $msg eq 'HASH' ? $msg : { msg => $msg };
43 12 100       39 die $class->new( map { defined $m->{$_} ? ( $_ => $m->{$_} ) : () } keys %$m );
  16         113  
44             }
45              
46             sub message {
47 21     21   2235 my ( $self, $msg ) = @_;
48 21         25 my $intro = "Caught @{[ref $self]}";
  21         71  
49 21 100 100     548 return defined($msg) && length($msg) ? "$intro: $msg" : $intro;
50             }
51              
52             sub as_string {
53 19     19   3781 my ($self) = @_;
54 19         602 my ( $message, $trace ) = ( $self->message( $self->msg ), $self->trace );
55 19 100       236 return length($trace) ? "$message\n\n$trace\n" : "$message\n";
56             }
57              
58             sub line_trace {
59 1     1   8 my ( undef, $filename, $line ) = caller(0);
60 1         11 return "Failure caught at $filename line $line.";
61             }
62              
63             for my $fn (qw/croak_trace confess_trace/) {
64 2     2   704 no strict 'refs';
  2         4  
  2         70  
65 2     2   9 no warnings 'once';
  2         3  
  2         287  
66             *{$fn} = sub {
67 2     2   36 require Carp;
68 2         6 local @failure::CARP_NOT = ( scalar caller );
69 2 100       712 chomp( my $trace = $fn eq 'croak_trace' ? Carp::shortmess('') : Carp::longmess('') );
70 2         132 return "Failure caught$trace";
71             };
72             }
73              
74             1;
75              
76              
77             # vim: ts=4 sts=4 sw=4 et:
78              
79             __END__