File Coverage

blib/lib/Exception/Simple.pm
Criterion Covered Total %
statement 51 51 100.0
branch 8 8 100.0
condition 3 8 37.5
subroutine 15 15 100.0
pod 2 3 66.6
total 79 85 92.9


line stmt bran cond sub pod time code
1             package Exception::Simple;
2 3     3   87173 use strict;
  3         7  
  3         263  
3 3     3   21 use warnings;
  3         4  
  3         296  
4              
5             our $VERSION = '1.000001';
6             $VERSION = eval $VERSION;
7              
8             use overload(
9             'fallback' => 1,
10 6     6   3971 '""' => sub { shift->as_string },
11 3     3   5474 );
  3         2171  
  3         184  
12 3     3   1741 use Carp;
  3         6  
  3         3031  
13              
14             # __public__ #
15             sub throw{
16 7     7 1 11538 my $self = shift;
17 7         315 my %params;
18              
19 7 100       25 if ( @_ == 1 ){
20 1         6 %params = ( 'error' => $_[0] );
21             } else {
22 6         28 %params = ( @_ );
23             }
24              
25 7         26 ( $params{'_package'}, $params{'_filename'}, $params{'_line'} ) = caller;
26              
27 7         995 die $self->_new( %params );
28             }
29              
30             sub rethrow{
31 3     3 1 1310 die shift;
32             }
33              
34             # __internal__ #
35              
36             sub import {
37 7     7   9779 my ( $pkg, $alias ) = ( @_ );
38              
39 7 100       70 if ( $alias ) {
40 4         12 my $target = caller;
41 4 100       177 croak "sub $alias already exists in $target" if $target->can($alias);
42              
43             {
44 3     3   22 no strict 'refs';
  3         6  
  3         681  
  2         2  
45 2     2   14 *{"${target}::${alias}"} = sub() { return $pkg };
  2         2025  
  2         4486  
46             }
47             }
48             }
49              
50             sub as_string{
51 6     6 0 12 my $self = shift;
52 6         17 return $self->error;
53             }
54              
55             sub _new{
56 7     7   16 my $invocant = shift;
57 7         28 my %params = ( @_ );
58              
59 7   33     51 my $class = ref( $invocant ) || $invocant;
60 7         21 my $self = bless( \%params, $class );
61              
62             #serious business
63 7         30 foreach my $key ( keys( %params ) ){
64 33 100       197 if ( !$self->can( $key ) ){
65 9         22 $self->_mk_accessor( $key );
66             }
67             }
68              
69 7         73 return $self;
70             }
71              
72             #creates an accessor for $name
73             sub _mk_accessor{
74 9     9   17 my ( $self, $name ) = @_;
75              
76 9   33     25 my $class = ref( $self ) || $self;
77             {
78 3     3   15 no strict 'refs';
  3         7  
  3         321  
  9         10  
79 9         59 *{$class . '::' . $name} = sub {
80 12   50 12   2886 return shift->{ $name } || undef;
81 9         41 };
82             }
83             }
84              
85             1;
86              
87             =head1 NAME
88              
89             Exception::Simple - simple exception class
90              
91             =head1 SYNOPSIS
92              
93             use Exception::Simple;
94             use Try::Tiny; #or just use eval {}, it's all good
95              
96             ### throw ###
97             try{
98             Exception::Simple->throw( 'oh noes!' );
99             } catch {
100             warn $_; #"oh noes!"
101             warn $_->error; #"oh noes!"
102             };
103              
104             my $data = {
105             'foo' => 'bar',
106             'fibble' => [qw/wibble bibble/],
107             };
108             try{
109             Exception::Simple->throw(
110             'error' => 'oh noes!',
111             'data' => $data,
112             );
113             } catch {
114             warn $_; #"oh noes!"
115             warn $_->error; #"oh noes!"
116              
117             warn $_->data->{'foo'}; #"bar"
118             };
119              
120              
121             =head1 DESCRIPTION
122              
123             pretty simple exception class. auto creates argument accessors.
124             simple, lightweight and extensible are this modules goals.
125              
126             =head1 ALIAS
127              
128             When using this module, you can specify a shortcut method, so you don't have to
129             type the full module name each time.
130              
131             This works by importing a sub with the name specified into the current namespace,
132             that returns the package name so you need to make sure this sub does not already exist,
133             or you'll get an error
134              
135             e.g.
136              
137             use Exception::Simple qw/E/;
138             use Try::Tiny; #or just use eval {}, it's all good
139              
140             ### throw ###
141             try{
142             E->throw( 'oh noes!' );
143             } catch {
144             warn ref $_; # Exception::Simple
145             warn $_; #"oh noes!"
146             warn $_->error; #"oh noes!"
147             };
148              
149             =head1 METHODS
150              
151             =head2 throw
152              
153             with just one argument $@->error is set
154             Exception::Simple->throw( 'error message' );
155             # $@ stringifies to $@->error
156              
157             or set multiple arguments (creates accessors)
158             Exception::Simple->throw(
159             error => 'error message',
160             data => 'custom attribute',
161             );
162             # warn $@->data or something
163              
164             =head2 rethrow
165              
166             say you catch an error, but then you want to uncatch it
167              
168             use Try::Tiny;
169              
170             try{
171             Exception:Simple->throw( 'foobar' );
172             } catch {
173             if ( $_ eq 'foobar' ){
174             #not our error, rethrow
175             $_->rethrow;
176             }
177             };
178              
179             =head2 error
180              
181             accessor for error message (set if only 1 arg is passed to throw)
182              
183             =head2 _package
184              
185             package that threw the exception
186              
187             =head2 _filename
188              
189             filename of the code that threw the exception
190              
191             =head2 _line
192              
193             line number that threw the exception
194              
195             =head1 CAVEATS
196              
197             If you pass in package, filename or line, they will be overwritten with the caller information
198              
199             If you don't pass in error, then you'll get an undef warning on stringify
200              
201             =head1 SUPPORT
202              
203             Please submit bugs through L
204              
205             For other issues, contact the maintainer
206              
207             =head1 AUTHOR
208              
209             Mark Ellis Emarkellis@cpan.orgE
210              
211             =head1 CONTRIBUTORS
212              
213             Stephen Thirlwall
214              
215             =head1 SEE ALSO
216              
217             L L
218              
219             =head1 LICENSE
220              
221             Copyright 2014 Mark Ellis Emarkellis@cpan.orgE
222              
223             This library is free software, you can redistribute it and/or modify
224             it under the same terms as Perl itself.
225              
226             =cut