File Coverage

blib/lib/Venus/Error.pm
Criterion Covered Total %
statement 139 145 95.8
branch 41 54 75.9
condition 19 29 65.5
subroutine 26 28 92.8
pod 14 17 82.3
total 239 273 87.5


line stmt bran cond sub pod time code
1             package Venus::Error;
2              
3 38     38   974 use 5.018;
  38         301  
4              
5 38     38   248 use strict;
  38         76  
  38         887  
6 38     38   197 use warnings;
  38         99  
  38         1426  
7              
8 38     38   274 use Venus::Class 'attr', 'base', 'with';
  38         116  
  38         332  
9              
10             base 'Venus::Kind::Utility';
11              
12             with 'Venus::Role::Explainable';
13             with 'Venus::Role::Stashable';
14              
15             use overload (
16             '""' => 'explain',
17 1     1   4 'eq' => sub{$_[0]->render eq "$_[1]"},
18 1     1   5 'ne' => sub{$_[0]->render ne "$_[1]"},
19 1     1   3 'qr' => sub{qr/@{[quotemeta($_[0]->render)]}/},
  1         5  
20 38         613 '~~' => 'explain',
21             fallback => 1,
22 38     38   334 );
  38         139  
23              
24             # ATTRIBUTES
25              
26             attr 'name';
27             attr 'context';
28             attr 'message';
29             attr 'verbose';
30              
31             # BUILDERS
32              
33             sub build_arg {
34 1     1 0 4 my ($self, $data) = @_;
35              
36             return {
37 1         4 message => $data,
38             };
39             }
40              
41             sub build_self {
42 353     353 0 1103 my ($self, $data) = @_;
43              
44 353 100       1348 $self->name($data->{name}) if $self->name;
45 353 100       1504 $self->context('(None)') if !$self->context;
46 353 100       1507 $self->message('Exception!') if !$self->message;
47 353 50 50     3330 $self->verbose($ENV{VENUS_ERROR_VERBOSE} // 1) if !exists $data->{verbose};
48 353 50 50     752 $self->trace($ENV{VENUS_ERROR_TRACE_OFFSET} // 2) if !@{$self->frames};
  353         1392  
49              
50 353         1057 return $self;
51             }
52              
53             # METHODS
54              
55             sub arguments {
56 3     3 1 12 my ($self, $index) = @_;
57              
58 3         15 my $captured = $self->captured;
59              
60 3 100       11 return undef if !$captured;
61              
62 2         10 my $arguments = $captured->{arguments};
63              
64 2 100       14 return $arguments if !defined $index;
65              
66 1 50       3 return undef if !$arguments;
67              
68 1         4 return $arguments->[$index];
69             }
70              
71              
72             sub as {
73 14     14 1 41 my ($self, $name) = @_;
74              
75 14         37 $name = $self->id($name);
76              
77 14         31 my $method = "as_${name}";
78              
79 14 100       49 $self = ref $self ? $self : $self->new;
80              
81 14 100       69 if (!$self->can($method)) {
82 6         32 return $self->do('name', $name);
83             }
84              
85 8         209 return $self->$method;
86             }
87              
88             sub assertion {
89 0     0 1 0 my ($self) = @_;
90              
91 0         0 my $assertion = $self->SUPER::assertion;
92              
93             $assertion->match('string')->format(sub{
94 0   0 0   0 (ref $self || $self)->new($_)
95 0         0 });
96              
97 0         0 return $assertion;
98             }
99              
100             sub callframe {
101 3     3 1 10 my ($self, $index) = @_;
102              
103 3         9 my $captured = $self->captured;
104              
105 3 100       20 return undef if !$captured;
106              
107 2         4 my $callframe = $captured->{callframe};
108              
109 2 100       11 return $callframe if !defined $index;
110              
111 1 50       35 return undef if !$callframe;
112              
113 1         6 return $callframe->[$index];
114             }
115              
116             sub captured {
117 7     7 1 16 my ($self) = @_;
118              
119 7         37 return $self->stash('captured');
120             }
121              
122             sub id {
123 2104     2104 0 3765 my ($self, $name) = @_;
124              
125 2104 100       6475 $name = lc $name =~ s/\W+/_/gr if $name;
126              
127 2104         9166 return $name;
128             }
129              
130             sub explain {
131 1248     1248 1 12004 my ($self) = @_;
132              
133 1248 50       1846 $self->trace(1, 1) if !@{$self->frames};
  1248         2953  
134              
135 1248         2562 my $frames = $self->{'$frames'};
136 1248         2961 my $message = $self->render;
137              
138 1248         16466 my @stacktrace = "$message" =~ s/^\s+|\s+$//gr;
139              
140 1248 50       3812 return join "\n", @stacktrace, "" if !$self->verbose;
141              
142 1248   100     3320 push @stacktrace, 'Name:', $self->name || '(None)';
143 1248         3267 push @stacktrace, 'Type:', ref($self);
144 1248   50     3299 push @stacktrace, 'Context:', $self->context || '(None)';
145              
146 38     38   37245 no warnings 'once';
  38         121  
  38         10130  
147              
148 1248         6673 require Data::Dumper;
149              
150 1248         2739 local $Data::Dumper::Indent = 1;
151 1248         2063 local $Data::Dumper::Trailingcomma = 0;
152 1248         1990 local $Data::Dumper::Purity = 0;
153 1248         2006 local $Data::Dumper::Pad = '';
154 1248         1999 local $Data::Dumper::Varname = 'VAR';
155 1248         1804 local $Data::Dumper::Useqq = 0;
156 1248         1830 local $Data::Dumper::Terse = 1;
157 1248         1890 local $Data::Dumper::Freezer = '';
158 1248         1850 local $Data::Dumper::Toaster = '';
159 1248         1920 local $Data::Dumper::Deepcopy = 1;
160 1248         1772 local $Data::Dumper::Quotekeys = 0;
161 1248         1900 local $Data::Dumper::Bless = 'bless';
162 1248         2031 local $Data::Dumper::Pair = ' => ';
163 1248         1703 local $Data::Dumper::Maxdepth = 0;
164 1248         1723 local $Data::Dumper::Maxrecurse = 1000;
165 1248         1697 local $Data::Dumper::Useperl = 0;
166 1248         2008 local $Data::Dumper::Sortkeys = 1;
167 1248         1859 local $Data::Dumper::Deparse = 1;
168 1248         1776 local $Data::Dumper::Sparseseen = 0;
169              
170 1248         3261 my $stashed = Data::Dumper->Dump([$self->stash]);
171              
172 1248         365620 $stashed =~ s/^'|'$//g;
173              
174 1248         2946 chomp $stashed;
175              
176 1248         2765 push @stacktrace, 'Stashed:', $stashed;
177 1248 100       3741 push @stacktrace, 'Traceback (reverse chronological order):' if @$frames > 1;
178              
179 38     38   345 use warnings 'once';
  38         103  
  38         40839  
180              
181 1248         8324 @stacktrace = (join("\n\n", grep defined, @stacktrace), '');
182              
183 1248         3797 for (my $i = 1; $i < @$frames; $i++) {
184 27685         39297 my $pack = $frames->[$i][0];
185 27685         33964 my $file = $frames->[$i][1];
186 27685         33600 my $line = $frames->[$i][2];
187 27685         34148 my $subr = $frames->[$i][3];
188              
189 27685         77119 push @stacktrace, "$subr\n in $file at line $line";
190             }
191              
192 1248         18172 return join "\n", @stacktrace, "";
193             }
194              
195             sub frames {
196 1963     1963 1 3490 my ($self) = @_;
197              
198 1963   100     9988 return $self->{'$frames'} //= [];
199             }
200              
201             sub is {
202 20     20 1 4569 my ($self, $name) = @_;
203              
204 20         66 $name = $self->id($name);
205              
206 20         106 my $method = "is_${name}";
207              
208 20 100 66     59 if ($self->name && !$self->can($method)) {
209 17 50       64 return $self->name eq $name ? true : false;
210             }
211              
212 3 50       65 return (ref $self ? $self: $self->new)->$method ? true : false;
    100          
213             }
214              
215             sub name {
216 2065     2065 1 66052 my ($self, $name) = @_;
217              
218 2065   66     4714 return $self->ITEM('name', $self->id($name) // ());
219             }
220              
221             sub of {
222 5     5 1 11 my ($self, $name) = @_;
223              
224 5         11 $name = $self->id($name);
225              
226 5         10 my $method = "of_${name}";
227              
228 5 50 33     12 if ($self->name && !$self->can($method)) {
229 5 100       12 return $self->name =~ /$name/ ? true : false;
230             }
231              
232 0 0       0 return (ref $self ? $self: $self->new)->$method ? true : false;
    0          
233             }
234              
235             sub frame {
236 2     2 1 7 my ($self, $index) = @_;
237              
238 2         6 my $frames = $self->frames;
239              
240 2   100     11 $index //= 0;
241              
242             return {
243 2         44 package => $frames->[$index][0],
244             filename => $frames->[$index][1],
245             line => $frames->[$index][2],
246             subroutine => $frames->[$index][3],
247             hasargs => $frames->[$index][4],
248             wantarray => $frames->[$index][5],
249             evaltext => $frames->[$index][6],
250             is_require => $frames->[$index][7],
251             hints => $frames->[$index][8],
252             bitmask => $frames->[$index][9],
253             hinthash => $frames->[$index][10],
254             };
255             }
256              
257             sub render {
258 1393     1393 1 42471 my ($self) = @_;
259              
260 1393         3752 my $message = $self->message;
261 1393         4734 my $stashed = $self->stash;
262              
263 1393         5672 while (my($key, $value) = each(%$stashed)) {
264 4083         8096 my $token = quotemeta $key;
265 4083         61545 $message =~ s/\{\{\s*$token\s*\}\}/$value/g;
266             }
267              
268 1393         4494 return $message;
269             }
270              
271             sub throw {
272 357     357 1 1215 my ($self, @args) = @_;
273              
274 357 100       1177 $self = $self->new(@args) if !ref $self;
275              
276 357         3008 die $self;
277             }
278              
279             sub trace {
280 356     356 1 893 my ($self, $offset, $limit) = @_;
281              
282 356         793 my $frames = $self->frames;
283              
284 356         888 @$frames = ();
285              
286 356   100     3831 for (my $i = $offset // 1; my @caller = caller($i); $i++) {
287 8021         23370 push @$frames, [@caller];
288              
289 8021 100 100     47975 last if defined $limit && $i + 1 == $offset + $limit;
290             }
291              
292 356         996 return $self;
293             }
294              
295             1;
296              
297              
298              
299             =head1 NAME
300              
301             Venus::Error - Error Class
302              
303             =cut
304              
305             =head1 ABSTRACT
306              
307             Error Class for Perl 5
308              
309             =cut
310              
311             =head1 SYNOPSIS
312              
313             package main;
314              
315             use Venus::Error;
316              
317             my $error = Venus::Error->new;
318              
319             # $error->throw;
320              
321             =cut
322              
323             =head1 DESCRIPTION
324              
325             This package represents a context-aware error (exception object). The default
326             for error verbosity can be controlled via the C
327             environment variable, e.g. a setting of C<0> disables stack traces. The default
328             trace-offset can be controlled via the C environment
329             variable, e.g. a setting of C<0> indicates no offset.
330              
331             =cut
332              
333             =head1 ATTRIBUTES
334              
335             This package has the following attributes:
336              
337             =cut
338              
339             =head2 name
340              
341             name(Str)
342              
343             This attribute is read-write, accepts C<(Str)> values, and is optional.
344              
345             =cut
346              
347             =head2 context
348              
349             context(Str)
350              
351             This attribute is read-write, accepts C<(Str)> values, is optional, and defaults to C<'(None)'>.
352              
353             =cut
354              
355             =head2 message
356              
357             message(Str)
358              
359             This attribute is read-write, accepts C<(Str)> values, is optional, and defaults to C<'Exception!'>.
360              
361             =cut
362              
363             =head2 verbose
364              
365             verbose(Int)
366              
367             This attribute is read-write, accepts C<(Int)> values, is optional, and defaults to C<1>.
368              
369             =cut
370              
371             =head1 INHERITS
372              
373             This package inherits behaviors from:
374              
375             L
376              
377             =cut
378              
379             =head1 INTEGRATES
380              
381             This package integrates behaviors from:
382              
383             L
384              
385             L
386              
387             =cut
388              
389             =head1 METHODS
390              
391             This package provides the following methods:
392              
393             =cut
394              
395             =head2 arguments
396              
397             arguments(number $index) (any)
398              
399             The arguments method returns the stashed arguments under L, or a
400             specific argument if an index is provided.
401              
402             I>
403              
404             =over 4
405              
406             =item arguments example 1
407              
408             # given: synopsis
409              
410             my $arguments = $error->arguments;
411              
412             # undef
413              
414             =back
415              
416             =over 4
417              
418             =item arguments example 2
419              
420             package main;
421              
422             use Venus::Throw;
423              
424             my $error = Venus::Throw->new->capture(1..4)->catch('error');
425              
426             my $arguments = $error->arguments;
427              
428             # [1..4]
429              
430             =back
431              
432             =over 4
433              
434             =item arguments example 3
435              
436             package main;
437              
438             use Venus::Throw;
439              
440             my $error = Venus::Throw->new->capture(1..4)->catch('error');
441              
442             my $arguments = $error->arguments(0);
443              
444             # 1
445              
446             =back
447              
448             =cut
449              
450             =head2 as
451              
452             as(string $name) (Venus::Error)
453              
454             The as method returns an error object using the return value(s) of the "as"
455             method specified, which should be defined as C<"as_${name}">, which will be
456             called automatically by this method. If no C<"as_${name}"> method exists, this
457             method will set the L attribute to the value provided.
458              
459             I>
460              
461             =over 4
462              
463             =item as example 1
464              
465             package System::Error;
466              
467             use Venus::Class;
468              
469             base 'Venus::Error';
470              
471             sub as_auth_error {
472             my ($self) = @_;
473              
474             return $self->do('message', 'auth_error');
475             }
476              
477             sub as_role_error {
478             my ($self) = @_;
479              
480             return $self->do('message', 'role_error');
481             }
482              
483             sub is_auth_error {
484             my ($self) = @_;
485              
486             return $self->message eq 'auth_error';
487             }
488              
489             sub is_role_error {
490             my ($self) = @_;
491              
492             return $self->message eq 'role_error';
493             }
494              
495             package main;
496              
497             my $error = System::Error->new->as('auth_error');
498              
499             $error->throw;
500              
501             # Exception! (isa Venus::Error)
502              
503             =back
504              
505             =over 4
506              
507             =item as example 2
508              
509             package System::Error;
510              
511             use Venus::Class;
512              
513             base 'Venus::Error';
514              
515             sub as_auth_error {
516             my ($self) = @_;
517              
518             return $self->do('message', 'auth_error');
519             }
520              
521             sub as_role_error {
522             my ($self) = @_;
523              
524             return $self->do('message', 'role_error');
525             }
526              
527             sub is_auth_error {
528             my ($self) = @_;
529              
530             return $self->message eq 'auth_error';
531             }
532              
533             sub is_role_error {
534             my ($self) = @_;
535              
536             return $self->message eq 'role_error';
537             }
538              
539             package main;
540              
541             my $error = System::Error->new->as('role_error');
542              
543             $error->throw;
544              
545             # Exception! (isa Venus::Error)
546              
547             =back
548              
549             =over 4
550              
551             =item as example 3
552              
553             package Virtual::Error;
554              
555             use Venus::Class;
556              
557             base 'Venus::Error';
558              
559             package main;
560              
561             my $error = Virtual::Error->new->as('on_save_error');
562              
563             $error->throw;
564              
565             # name is "on_save_error"
566              
567             # Exception! (isa Venus::Error)
568              
569             =back
570              
571             =over 4
572              
573             =item as example 4
574              
575             package Virtual::Error;
576              
577             use Venus::Class;
578              
579             base 'Venus::Error';
580              
581             package main;
582              
583             my $error = Virtual::Error->new->as('on.SAVE.error');
584              
585             $error->throw;
586              
587             # name is "on_save_error"
588              
589             # Exception! (isa Venus::Error)
590              
591             =back
592              
593             =cut
594              
595             =head2 callframe
596              
597             callframe(number $index) (any)
598              
599             The callframe method returns the stashed callframe under L, or a
600             specific argument if an index is provided.
601              
602             I>
603              
604             =over 4
605              
606             =item callframe example 1
607              
608             # given: synopsis
609              
610             my $callframe = $error->callframe;
611              
612             # undef
613              
614             =back
615              
616             =over 4
617              
618             =item callframe example 2
619              
620             package main;
621              
622             use Venus::Throw;
623              
624             my $error = Venus::Throw->new->do('frame', 0)->capture->catch('error');
625              
626             my $callframe = $error->callframe;
627              
628             # [...]
629              
630             =back
631              
632             =over 4
633              
634             =item callframe example 3
635              
636             package main;
637              
638             use Venus::Throw;
639              
640             my $error = Venus::Throw->new->do('frame', 0)->capture->catch('error');
641              
642             my $package = $error->callframe(0);
643              
644             # 'main'
645              
646             =back
647              
648             =cut
649              
650             =head2 captured
651              
652             captured() (hashref)
653              
654             The captured method returns the value stashed as C<"captured">.
655              
656             I>
657              
658             =over 4
659              
660             =item captured example 1
661              
662             # given: synopsis
663              
664             my $captured = $error->captured;
665              
666             # undef
667              
668             =back
669              
670             =cut
671              
672             =head2 explain
673              
674             explain() (string)
675              
676             The explain method returns the error message and is used in stringification
677             operations.
678              
679             I>
680              
681             =over 4
682              
683             =item explain example 1
684              
685             # given: synopsis;
686              
687             my $explain = $error->explain;
688              
689             # "Exception! in ...
690              
691             =back
692              
693             =cut
694              
695             =head2 frame
696              
697             frame(number $index) (hashref)
698              
699             The frame method returns the data from C on the frames captured, and
700             returns a hashref where the keys map to the keys described by
701             L.
702              
703             I>
704              
705             =over 4
706              
707             =item frame example 1
708              
709             # given: synopsis;
710              
711             my $frame = $error->frame;
712              
713             # {
714             # 'bitmask' => '...',
715             # 'evaltext' => '...',
716             # 'filename' => '...',
717             # 'hasargs' => '...',
718             # 'hinthash' => '...',
719             # 'hints' => '...',
720             # 'is_require' => '...',
721             # 'line' => '...',
722             # 'package' => '...',
723             # 'subroutine' => '...',
724             # 'wantarray' => '...',
725             # }
726              
727             =back
728              
729             =over 4
730              
731             =item frame example 2
732              
733             # given: synopsis;
734              
735             my $frame = $error->frame(1);
736              
737             # {
738             # 'bitmask' => '...',
739             # 'evaltext' => '...',
740             # 'filename' => '...',
741             # 'hasargs' => '...',
742             # 'hinthash' => '...',
743             # 'hints' => '...',
744             # 'is_require' => '...',
745             # 'line' => '...',
746             # 'package' => '...',
747             # 'subroutine' => '...',
748             # 'wantarray' => '...',
749             # }
750              
751             =back
752              
753             =cut
754              
755             =head2 frames
756              
757             frames() (arrayref)
758              
759             The frames method returns the compiled and stashed stack trace data.
760              
761             I>
762              
763             =over 4
764              
765             =item frames example 1
766              
767             # given: synopsis;
768              
769             my $frames = $error->frames;
770              
771             # [
772             # ...
773             # [
774             # "main",
775             # "t/Venus_Error.t",
776             # ...
777             # ],
778             # ]
779              
780             =back
781              
782             =cut
783              
784             =head2 is
785              
786             is(string $name) (boolean)
787              
788             The is method returns truthy or falsy based on the return value(s) of the "is"
789             method specified, which should be defined as C<"is_${name}">, which will be
790             called automatically by this method. If no C<"is_${name}"> method exists, this
791             method will check if the L attribute is equal to the value provided.
792              
793             I>
794              
795             =over 4
796              
797             =item is example 1
798              
799             package System::Error;
800              
801             use Venus::Class;
802              
803             base 'Venus::Error';
804              
805             sub as_auth_error {
806             my ($self) = @_;
807              
808             return $self->do('message', 'auth_error');
809             }
810              
811             sub as_role_error {
812             my ($self) = @_;
813              
814             return $self->do('message', 'role_error');
815             }
816              
817             sub is_auth_error {
818             my ($self) = @_;
819              
820             return $self->message eq 'auth_error';
821             }
822              
823             sub is_role_error {
824             my ($self) = @_;
825              
826             return $self->message eq 'role_error';
827             }
828              
829             package main;
830              
831             my $is = System::Error->new->as('auth_error')->is('auth_error');
832              
833             # 1
834              
835             =back
836              
837             =over 4
838              
839             =item is example 2
840              
841             package System::Error;
842              
843             use Venus::Class;
844              
845             base 'Venus::Error';
846              
847             sub as_auth_error {
848             my ($self) = @_;
849              
850             return $self->do('message', 'auth_error');
851             }
852              
853             sub as_role_error {
854             my ($self) = @_;
855              
856             return $self->do('message', 'role_error');
857             }
858              
859             sub is_auth_error {
860             my ($self) = @_;
861              
862             return $self->message eq 'auth_error';
863             }
864              
865             sub is_role_error {
866             my ($self) = @_;
867              
868             return $self->message eq 'role_error';
869             }
870              
871             package main;
872              
873             my $is = System::Error->as('auth_error')->is('auth_error');
874              
875             # 1
876              
877             =back
878              
879             =over 4
880              
881             =item is example 3
882              
883             package System::Error;
884              
885             use Venus::Class;
886              
887             base 'Venus::Error';
888              
889             sub as_auth_error {
890             my ($self) = @_;
891              
892             return $self->do('message', 'auth_error');
893             }
894              
895             sub as_role_error {
896             my ($self) = @_;
897              
898             return $self->do('message', 'role_error');
899             }
900              
901             sub is_auth_error {
902             my ($self) = @_;
903              
904             return $self->message eq 'auth_error';
905             }
906              
907             sub is_role_error {
908             my ($self) = @_;
909              
910             return $self->message eq 'role_error';
911             }
912              
913             package main;
914              
915             my $is = System::Error->as('auth_error')->is('role_error');
916              
917             # 0
918              
919             =back
920              
921             =over 4
922              
923             =item is example 4
924              
925             package Virtual::Error;
926              
927             use Venus::Class;
928              
929             base 'Venus::Error';
930              
931             package main;
932              
933             my $is = Virtual::Error->new->as('on_save_error')->is('on_save_error');
934              
935             # 1
936              
937             =back
938              
939             =over 4
940              
941             =item is example 5
942              
943             package Virtual::Error;
944              
945             use Venus::Class;
946              
947             base 'Venus::Error';
948              
949             package main;
950              
951             my $is = Virtual::Error->new->as('on.SAVE.error')->is('on_save_error');
952              
953             # 1
954              
955             =back
956              
957             =cut
958              
959             =head2 of
960              
961             of(string $name) (boolean)
962              
963             The of method returns truthy or falsy based on the return value(s) of the "of"
964             method specified, which should be defined as C<"of_${name}">, which will be
965             called automatically by this method. If no C<"of_${name}"> method exists, this
966             method will check if the L attribute contains the value provided.
967              
968             I>
969              
970             =over 4
971              
972             =item of example 1
973              
974             package System::Error;
975              
976             use Venus::Class;
977              
978             base 'Venus::Error';
979              
980             sub as_auth_error {
981             my ($self) = @_;
982              
983             return $self->do('name', 'auth_error');
984             }
985              
986             sub as_role_error {
987             my ($self) = @_;
988              
989             return $self->do('name', 'role_error');
990             }
991              
992             sub is_auth_error {
993             my ($self) = @_;
994              
995             return $self->name eq 'auth_error';
996             }
997              
998             sub is_role_error {
999             my ($self) = @_;
1000              
1001             return $self->name eq 'role_error';
1002             }
1003              
1004             package main;
1005              
1006             my $of = System::Error->as('auth_error')->of('role');
1007              
1008             # 0
1009              
1010             =back
1011              
1012             =over 4
1013              
1014             =item of example 2
1015              
1016             package System::Error;
1017              
1018             use Venus::Class;
1019              
1020             base 'Venus::Error';
1021              
1022             sub as_auth_error {
1023             my ($self) = @_;
1024              
1025             return $self->do('name', 'auth_error');
1026             }
1027              
1028             sub as_role_error {
1029             my ($self) = @_;
1030              
1031             return $self->do('name', 'role_error');
1032             }
1033              
1034             sub is_auth_error {
1035             my ($self) = @_;
1036              
1037             return $self->name eq 'auth_error';
1038             }
1039              
1040             sub is_role_error {
1041             my ($self) = @_;
1042              
1043             return $self->name eq 'role_error';
1044             }
1045              
1046             package main;
1047              
1048             my $of = System::Error->as('auth_error')->of('auth');
1049              
1050             # 1
1051              
1052             =back
1053              
1054             =over 4
1055              
1056             =item of example 3
1057              
1058             package System::Error;
1059              
1060             use Venus::Class;
1061              
1062             base 'Venus::Error';
1063              
1064             sub as_auth_error {
1065             my ($self) = @_;
1066              
1067             return $self->do('name', 'auth_error');
1068             }
1069              
1070             sub as_role_error {
1071             my ($self) = @_;
1072              
1073             return $self->do('name', 'role_error');
1074             }
1075              
1076             sub is_auth_error {
1077             my ($self) = @_;
1078              
1079             return $self->name eq 'auth_error';
1080             }
1081              
1082             sub is_role_error {
1083             my ($self) = @_;
1084              
1085             return $self->name eq 'role_error';
1086             }
1087              
1088             package main;
1089              
1090             my $of = System::Error->as('auth_error')->of('role_error');
1091              
1092             # 0
1093              
1094             =back
1095              
1096             =over 4
1097              
1098             =item of example 4
1099              
1100             package Virtual::Error;
1101              
1102             use Venus::Class;
1103              
1104             base 'Venus::Error';
1105              
1106             package main;
1107              
1108             my $of = Virtual::Error->new->as('on_save_error')->of('on.save');
1109              
1110             # 1
1111              
1112             =back
1113              
1114             =over 4
1115              
1116             =item of example 5
1117              
1118             package Virtual::Error;
1119              
1120             use Venus::Class;
1121              
1122             base 'Venus::Error';
1123              
1124             package main;
1125              
1126             my $of = Virtual::Error->new->as('on.SAVE.error')->of('on.save');
1127              
1128             # 1
1129              
1130             =back
1131              
1132             =cut
1133              
1134             =head2 render
1135              
1136             render() (string)
1137              
1138             The render method replaces tokens in the message with values from the stash and
1139             returns the formatted string. The token style and formatting operation is
1140             equivalent to the L operation.
1141              
1142             I>
1143              
1144             =over 4
1145              
1146             =item render example 1
1147              
1148             # given: synopsis
1149              
1150             package main;
1151              
1152             $error->message('Signal received: {{signal}}');
1153              
1154             $error->stash(signal => 'SIGKILL');
1155              
1156             my $render = $error->render;
1157              
1158             # "Signal received: SIGKILL"
1159              
1160             =back
1161              
1162             =cut
1163              
1164             =head2 throw
1165              
1166             throw(any @data) (Venus::Error)
1167              
1168             The throw method throws an error if the invocant is an object, or creates an
1169             error object using the arguments provided and throws the created object.
1170              
1171             I>
1172              
1173             =over 4
1174              
1175             =item throw example 1
1176              
1177             # given: synopsis;
1178              
1179             my $throw = $error->throw;
1180              
1181             # bless({ ... }, 'Venus::Error')
1182              
1183             =back
1184              
1185             =cut
1186              
1187             =head2 trace
1188              
1189             trace(number $offset, number $limit) (Venus::Error)
1190              
1191             The trace method compiles a stack trace and returns the object. By default it
1192             skips the first frame.
1193              
1194             I>
1195              
1196             =over 4
1197              
1198             =item trace example 1
1199              
1200             # given: synopsis;
1201              
1202             my $trace = $error->trace;
1203              
1204             # bless({ ... }, 'Venus::Error')
1205              
1206             =back
1207              
1208             =over 4
1209              
1210             =item trace example 2
1211              
1212             # given: synopsis;
1213              
1214             my $trace = $error->trace(0, 1);
1215              
1216             # bless({ ... }, 'Venus::Error')
1217              
1218             =back
1219              
1220             =over 4
1221              
1222             =item trace example 3
1223              
1224             # given: synopsis;
1225              
1226             my $trace = $error->trace(0, 2);
1227              
1228             # bless({ ... }, 'Venus::Error')
1229              
1230             =back
1231              
1232             =cut
1233              
1234             =head1 OPERATORS
1235              
1236             This package overloads the following operators:
1237              
1238             =cut
1239              
1240             =over 4
1241              
1242             =item operation: C<("")>
1243              
1244             This package overloads the C<""> operator.
1245              
1246             B
1247              
1248             # given: synopsis;
1249              
1250             my $result = "$error";
1251              
1252             # "Exception!"
1253              
1254             =back
1255              
1256             =over 4
1257              
1258             =item operation: C<(eq)>
1259              
1260             This package overloads the C operator.
1261              
1262             B
1263              
1264             # given: synopsis;
1265              
1266             my $result = $error eq 'Exception!';
1267              
1268             # 1
1269              
1270             =back
1271              
1272             =over 4
1273              
1274             =item operation: C<(ne)>
1275              
1276             This package overloads the C operator.
1277              
1278             B
1279              
1280             # given: synopsis;
1281              
1282             my $result = $error ne 'exception!';
1283              
1284             # 1
1285              
1286             =back
1287              
1288             =over 4
1289              
1290             =item operation: C<(qr)>
1291              
1292             This package overloads the C operator.
1293              
1294             B
1295              
1296             # given: synopsis;
1297              
1298             my $test = 'Exception!' =~ qr/$error/;
1299              
1300             # 1
1301              
1302             =back
1303              
1304             =over 4
1305              
1306             =item operation: C<(~~)>
1307              
1308             This package overloads the C<~~> operator.
1309              
1310             B
1311              
1312             # given: synopsis;
1313              
1314             my $result = $error ~~ 'Exception!';
1315              
1316             # 1
1317              
1318             =back
1319              
1320             =head1 AUTHORS
1321              
1322             Awncorp, C
1323              
1324             =cut
1325              
1326             =head1 LICENSE
1327              
1328             Copyright (C) 2000, Awncorp, C.
1329              
1330             This program is free software, you can redistribute it and/or modify it under
1331             the terms of the Apache license version 2.0.
1332              
1333             =cut