File Coverage

blib/lib/Venus/Fault.pm
Criterion Covered Total %
statement 47 47 100.0
branch 6 8 75.0
condition 9 9 100.0
subroutine 12 12 100.0
pod 4 5 80.0
total 78 81 96.3


line stmt bran cond sub pod time code
1             package Venus::Fault;
2              
3 2     2   49 use 5.018;
  2         7  
4              
5 2     2   10 use strict;
  2         3  
  2         53  
6 2     2   8 use warnings;
  2         4  
  2         306  
7              
8             use overload (
9             '""' => 'explain',
10 1     1   19 'eq' => sub{$_[0]->{message} eq "$_[1]"},
11 1     1   21 'ne' => sub{$_[0]->{message} ne "$_[1]"},
12 1     1   3 'qr' => sub{qr/@{[quotemeta($_[0]->{message})]}/},
  1         39  
13 2         24 '~~' => 'explain',
14             fallback => 1,
15 2     2   13 );
  2         5  
16              
17             # METHODS
18              
19             sub new {
20 12   100 12 0 87 return bless({message => $_[1] || 'Exception!'})->trace;
21             }
22              
23             sub explain {
24 29     29 1 761 my ($self) = @_;
25              
26 29 50       58 $self->trace(1) if !@{$self->frames};
  29         54  
27              
28 29         48 my $frames = $self->{'$frames'};
29              
30 29         46 my $file = $frames->[0][1];
31 29         45 my $line = $frames->[0][2];
32 29         43 my $pack = $frames->[0][0];
33 29         46 my $subr = $frames->[0][3];
34              
35 29         52 my $message = $self->{message};
36              
37 29         89 my @stacktrace = ("$message in $file at line $line");
38              
39 29 100       71 push @stacktrace, 'Traceback (reverse chronological order):' if @$frames > 1;
40              
41 29         115 @stacktrace = (join("\n\n", grep defined, @stacktrace), '');
42              
43 29         73 for (my $i = 1; $i < @$frames; $i++) {
44 338         490 my $pack = $frames->[$i][0];
45 338         411 my $file = $frames->[$i][1];
46 338         406 my $line = $frames->[$i][2];
47 338         428 my $subr = $frames->[$i][3];
48              
49 338         992 push @stacktrace, "$subr\n in $file at line $line";
50             }
51              
52 29         269 return join "\n", @stacktrace, "";
53             }
54              
55             sub frames {
56 48     48 1 76 my ($self) = @_;
57              
58 48   100     305 return $self->{'$frames'} //= [];
59             }
60              
61             sub throw {
62 2     2 1 6 my ($self, @args) = @_;
63              
64 2 50       7 $self = $self->new(@args) if !ref $self;
65              
66 2         28 die $self;
67             }
68              
69             sub trace {
70 15     15 1 42 my ($self, $offset, $limit) = @_;
71              
72 15         36 my $frames = $self->frames;
73              
74 15         54 @$frames = ();
75              
76 15   100     144 for (my $i = $offset // 1; my @caller = caller($i); $i++) {
77 199         542 push @$frames, [@caller];
78              
79 199 100 100     1176 last if defined $limit && $i + 1 == $offset + $limit;
80             }
81              
82 15         287 return $self;
83             }
84              
85             1;
86              
87              
88              
89             =head1 NAME
90              
91             Venus::Fault - Fault Class
92              
93             =cut
94              
95             =head1 ABSTRACT
96              
97             Fault Class for Perl 5
98              
99             =cut
100              
101             =head1 SYNOPSIS
102              
103             package main;
104              
105             use Venus::Fault;
106              
107             my $fault = Venus::Fault->new;
108              
109             # $fault->throw;
110              
111             =cut
112              
113             =head1 DESCRIPTION
114              
115             This package represents a generic system error (exception object).
116              
117             =cut
118              
119             =head1 METHODS
120              
121             This package provides the following methods:
122              
123             =cut
124              
125             =head2 explain
126              
127             explain() (string)
128              
129             The explain method returns the error message and is used in stringification
130             operations.
131              
132             I>
133              
134             =over 4
135              
136             =item explain example 1
137              
138             # given: synopsis;
139              
140             my $explain = $fault->explain;
141              
142             # "Exception! in ...
143              
144             =back
145              
146             =cut
147              
148             =head2 frames
149              
150             frames() (arrayref)
151              
152             The frames method returns the compiled and stashed stack trace data.
153              
154             I>
155              
156             =over 4
157              
158             =item frames example 1
159              
160             # given: synopsis;
161              
162             my $frames = $fault->frames;
163              
164             # [
165             # ...
166             # [
167             # "main",
168             # "t/Venus_Fault.t",
169             # ...
170             # ],
171             # ]
172              
173             =back
174              
175             =cut
176              
177             =head2 throw
178              
179             throw(string $message) (Venus::Fault)
180              
181             The throw method throws an error if the invocant is an object, or creates an
182             error object using the arguments provided and throws the created object.
183              
184             I>
185              
186             =over 4
187              
188             =item throw example 1
189              
190             # given: synopsis;
191              
192             my $throw = $fault->throw;
193              
194             # bless({ ... }, 'Venus::Fault')
195              
196             =back
197              
198             =cut
199              
200             =head2 trace
201              
202             trace(number $offset, number $limit) (Venus::Fault)
203              
204             The trace method compiles a stack trace and returns the object. By default it
205             skips the first frame.
206              
207             I>
208              
209             =over 4
210              
211             =item trace example 1
212              
213             # given: synopsis;
214              
215             my $trace = $fault->trace;
216              
217             # bless({ ... }, 'Venus::Fault')
218              
219             =back
220              
221             =over 4
222              
223             =item trace example 2
224              
225             # given: synopsis;
226              
227             my $trace = $fault->trace(0, 1);
228              
229             # bless({ ... }, 'Venus::Fault')
230              
231             =back
232              
233             =over 4
234              
235             =item trace example 3
236              
237             # given: synopsis;
238              
239             my $trace = $fault->trace(0, 2);
240              
241             # bless({ ... }, 'Venus::Fault')
242              
243             =back
244              
245             =cut
246              
247             =head1 OPERATORS
248              
249             This package overloads the following operators:
250              
251             =cut
252              
253             =over 4
254              
255             =item operation: C<("")>
256              
257             This package overloads the C<""> operator.
258              
259             B
260              
261             # given: synopsis;
262              
263             my $result = "$fault";
264              
265             # "Exception!"
266              
267             =back
268              
269             =over 4
270              
271             =item operation: C<(eq)>
272              
273             This package overloads the C operator.
274              
275             B
276              
277             # given: synopsis;
278              
279             my $result = $fault eq 'Exception!';
280              
281             # 1
282              
283             =back
284              
285             =over 4
286              
287             =item operation: C<(ne)>
288              
289             This package overloads the C operator.
290              
291             B
292              
293             # given: synopsis;
294              
295             my $result = $fault ne 'exception!';
296              
297             # 1
298              
299             =back
300              
301             =over 4
302              
303             =item operation: C<(qr)>
304              
305             This package overloads the C operator.
306              
307             B
308              
309             # given: synopsis;
310              
311             my $test = 'Exception!' =~ qr/$fault/;
312              
313             # 1
314              
315             =back
316              
317             =over 4
318              
319             =item operation: C<(~~)>
320              
321             This package overloads the C<~~> operator.
322              
323             B
324              
325             # given: synopsis;
326              
327             my $result = $fault ~~ 'Exception!';
328              
329             # 1
330              
331             =back
332              
333             =head1 AUTHORS
334              
335             Awncorp, C
336              
337             =cut
338              
339             =head1 LICENSE
340              
341             Copyright (C) 2000, Awncorp, C.
342              
343             This program is free software, you can redistribute it and/or modify it under
344             the terms of the Apache license version 2.0.
345              
346             =cut