File Coverage

blib/lib/Future/Exception.pm
Criterion Covered Total %
statement 24 24 100.0
branch 2 2 100.0
condition n/a
subroutine 10 10 100.0
pod 3 7 42.8
total 39 43 90.7


line stmt bran cond sub pod time code
1             # You may distribute under the terms of either the GNU General Public License
2             # or the Artistic License (the same terms as Perl itself)
3             #
4             # (C) Paul Evans, 2019 -- leonerd@leonerd.org.uk
5              
6             package Future::Exception 0.52;
7              
8 33     33   479 use v5.14;
  33         119  
9 33     33   169 use warnings;
  33         66  
  33         2606  
10              
11             =head1 NAME
12              
13             C - an exception type for failed Ls
14              
15             =head1 SYNOPSIS
16              
17             =for highlighter language=perl
18              
19             use Scalar::Util qw( blessed );
20             use Syntax::Keyword::Try;
21              
22             try {
23             my $f = ...;
24             my @result = $f->result;
25             ...
26             }
27             catch {
28             if( blessed($@) and $@->isa( "Future::Exception" ) {
29             print STDERR "The ", $@->category, " failed: ", $@->message, "\n";
30             }
31             }
32              
33             =head1 DESCRIPTION
34              
35             The C method on a failed L instance will throw an exception to
36             indicate that the future failed. A failed future can contain a failure
37             category name and other details as well as the failure message, so in this
38             case the exception will be an instance of C to make these
39             values accessible.
40              
41             Users should not depend on exact class name matches, but instead rely on
42             inheritence, as a later version of this implementation might dynamically
43             create subclasses whose names are derived from the Future failure category
44             string, to assist with type matching. Note the use of C<< ->isa >> in the
45             SYNOPSIS example.
46              
47             =cut
48              
49             use overload
50 33         290 '""' => "message",
51 33     33   209 fallback => 1;
  33         88  
52              
53             =head1 CONSTRUCTOR
54              
55             =head2 from_future
56              
57             $e = Future::Exception->from_future( $f );
58              
59             Constructs a new C wrapping the given failed future.
60              
61             =cut
62              
63             sub from_future
64             {
65 1     1 1 2 my $class = shift;
66 1         39 my ( $f ) = @_;
67 1         5 return $class->new( $f->failure );
68             }
69              
70 5     5 0 9 sub new { my $class = shift; bless [ @_ ], $class; }
  5         26  
71              
72             =head1 ACCESSORS
73              
74             $message = $e->message;
75             $category = $e->category;
76             @details = $e->details;
77              
78             Additionally, the object will stringify to return the message value, for the
79             common use-case of printing, regexp testing, or other behaviours.
80              
81             =cut
82              
83 10     10 0 9158 sub message { shift->[0] }
84 5     5 0 21 sub category { shift->[1] }
85 5     5 0 12 sub details { my $self = shift; @{$self}[2..$#$self] }
  5         13  
  5         29  
86              
87             =head1 METHODS
88              
89             =cut
90              
91             =head2 throw
92              
93             Future::Exception->throw( $message, $category, @details );
94              
95             I
96              
97             Constructs a new exception object and throws it using C. This method
98             will not return, as it raises the exception directly.
99              
100             If C<$message> does not end in a linefeed then the calling file and line
101             number are appended to it, in the same way C does.
102              
103             =cut
104              
105             sub throw
106             {
107 2     2 1 1166 my $class = shift;
108 2         7 my ( $message, $category, @details ) = @_;
109 2 100       16 $message =~ m/\n$/ or
110             $message .= sprintf " at %s line %d.\n", ( caller )[1,2];
111 2         7 die $class->new( $message, $category, @details );
112             }
113              
114             # TODO: consider a 'croak' method that uses Carp::shortmess to find a suitable
115             # file/linenumber
116              
117             =head2 as_future
118              
119             $f = $e->as_future;
120              
121             Returns a new C object in a failed state matching the exception.
122              
123             =cut
124              
125             sub as_future
126             {
127 1     1 1 3 my $self = shift;
128 1         4 return Future->fail( $self->message, $self->category, $self->details );
129             }
130              
131             =head1 AUTHOR
132              
133             Paul Evans
134              
135             =cut
136              
137             0x55AA;