File Coverage

blib/lib/Error/Helper.pm
Criterion Covered Total %
statement 6 81 7.4
branch 0 18 0.0
condition 0 51 0.0
subroutine 2 11 18.1
pod 9 9 100.0
total 17 170 10.0


line stmt bran cond sub pod time code
1             package Error::Helper;
2              
3 2     2   419025 use warnings;
  2         4  
  2         144  
4 2     2   44 use strict;
  2         3  
  2         3905  
5              
6             =head1 NAME
7              
8             Error::Helper - Provides some easy error related methods.
9              
10             =head1 VERSION
11              
12             Version 2.1.0
13              
14             =cut
15              
16             our $VERSION = '2.1.0';
17              
18             our $error = undef;
19             our $perror = undef;
20             our $errorLine = undef;
21             our $errorFilename = undef;
22             our $errorString = '';
23             our $errorFlag = undef;
24             our $errorPackage = undef;
25             our $errorPackageShort = undef;
26             our $errorSub = undef;
27             our $errorSubShort = undef;
28              
29             =head1 SYNOPSIS
30              
31             Below is a example script showing it's usage.
32              
33             use warnings;
34             use strict;
35              
36             {
37             package Foo;
38             use base 'Error::Helper';
39              
40             sub new {
41             my $arg = $_[1];
42              
43             my $self = {
44             perror => undef,
45             error => undef,
46             errorLine => undef,
47             errorFilename => undef,
48             errorString => "",
49             errorExtra => {
50             all_errors_fatal => 0,
51             flags => {
52             1 => 'UndefArg',
53             2 => 'test',
54             3 => 'derp',
55             4 => 'test2',
56             },
57             fatal_flags => {
58             derp => 1,
59             },
60             perror_not_fatal => 0,
61             },
62             };
63             bless $self;
64              
65             # error if $arg is set to "test"
66             if ( defined($arg)
67             && $arg eq "test" )
68             {
69             $self->{perror} = 1;
70             $self->{error} = 2;
71             $self->{errorString} = 'A value of "test" has been set';
72             $self->warn;
73             return $self;
74             }
75              
76             # error if $arg is set to "test2", error fatally
77             if ( defined($arg)
78             && $arg eq "test" )
79             {
80             $self->{perror} = 1;
81             $self->{error} = 4;
82             $self->{errorString} = 'A value of "test" has been set';
83             $self->warn;
84             return $self;
85             }
86              
87             return $self;
88             } ## end sub new
89              
90             sub foo {
91             my $self = $_[0];
92             my $a = $_[1];
93              
94             if ( !$self->errorblank ) {
95             return undef;
96             }
97              
98             if ( !defined($a) ) {
99             $self->{error} = 1;
100             $self->{errorString} = 'No value specified';
101             $self->warn;
102             return undef;
103             }
104              
105             # this will be fatal as it error flag derp is set to fatal
106             if ( $a eq 'derp' ) {
107             $self->{error} = 3;
108             $self->{errorString} = 'foo was called with a value of derp';
109             $self->warn;
110             }
111              
112             return 1;
113             } ## end sub foo
114             }
115              
116             my $foo_obj;
117             eval {
118             $foo_obj = Foo->new( $ARGV[0] );
119             # will never be evaulated as perrors are fatal
120             if ( $foo_obj->error ) {
121             warn( 'error:' . $foo_obj->error . ': ' . $foo_obj->errorString );
122             exit $foo_obj->error;
123             }
124             };
125             if ($@) {
126             print 'Error: ' . $Error::Helper::error .
127             "\nError String: " . $Error::Helper::errorString .
128             "\nError Flag: " . $Error::Helper::errorFlag .
129             "\nError File: " . $Error::Helper::errorFilename .
130             "\nError Line: " . $Error::Helper::errorLine .
131             "\nError Sub: " . $Error::Helper::errorSub .
132             "\nError Sub Short: " . $Error::Helper::errorSubShort .
133             "\nError Package: " . $Error::Helper::errorPackage .
134             "\nError PackageShort: " . $Error::Helper::errorPackageShort . "\n";
135              
136             exit $Error::Helper::error;
137             }
138              
139             # catches fatal errors
140             eval{
141             $foo_obj->foo( $ARGV[1] );
142             };
143             if ($@) {
144             # do something...
145             warn( '$foo_obj->foo( $ARGV[1] ) errored.... '.$@);
146             if ($foo_obj->errorFlag eq 'derp') {
147             warn('error flag derp found... calling again with a value of default');
148             $foo_obj->foo( 'default' );
149             }
150             } elsif ($foo_obj->error) {
151             # do something...
152             warn( '$foo_obj->foo( $ARGV[1] ) errored');
153             }
154              
155             There are five required variables in the blessed hash object.
156              
157             - $self->{error} :: This contains the current error code.
158             - Type :: int or undef
159              
160             - $self->{errorFilename} :: File from which $self->warn was called.
161             - Type :: string or undef
162              
163             - $self->{errorLine} :: Line from which $self->warn was called.
164             - Type :: int or undef
165              
166             - $self->{errorString} :: This contains a description of the current error.
167             - Type :: string or undef
168              
169             - $self->{perror} :: This is set to true is a permanent error is present.
170             If note, it needs set to false.
171             - Type :: Perl boolean
172              
173             The following are optional.
174              
175             - $self->{errorExtra} :: This is a hash reserved for any additional Error::Helper items.
176              
177             - $self->{errorExtra}{all_errors_fatal} :: If true, this will die when $self->warn is called instead of
178             printing the error to STDERR. This is for if you want to use it eval for capturing errors and this
179             module more for handling grabbing error specifics, such as dieing and additional code based on the
180             return of $self->errorFlag.
181             - Type :: Perl boolean
182             - Default :: undef
183              
184             - $self->{errorExtra}{fatal_errors} :: This is a hash in which the keys are errors codes that are fatal. When
185             $self->warn is called it will check if the error code is fatal or not. $self->{errorExtra}{fatal_errors}{33}=>1
186             would be fatal, but $self->{errorExtra}{fatal_errors}{33}=>0 would now.
187              
188             - $self->{errorExtra}{flags} :: This hash contains error integer to flag mapping. The
189             keys are the error integer and the value is the flag. For any unmatched error
190             integers, 'other' is returned.
191              
192             - $self->{errorExtra}{fatal_flags} :: This is a hash in which the keys are error flags that are fatal. When
193             $self->warn is called it will check if the flag for the error code is fatal or not. For the flag foo
194             $self->{errorExtra}{fatal_flags}{foo}=>1 would be fatal, but
195             $self->{errorExtra}{fatal_flags}{foo}=>0 would now.
196              
197             - $self->{errorExtra}{perror_not_fatal} :: Controls if $self->{perror} is fatal or not.
198             - Type :: Perl boolean
199             - Default :: undef
200              
201             This module also sets several other variables as well for when something like a new method is called
202             and dies, before something blessed can be returned. These allow examining the the error that resulted in it dieing.
203              
204             The following are mapped to the the ones above.
205              
206             $Error::Helper::perror
207             $Error::Helper::error
208             $Error::Helper::errorString
209             $Error::Helper::errorFlag
210             $Error::Helper::errorFilename
211             $Error::Helper::errorLine
212              
213             The following don't have mappings above.
214              
215             - $Error::Helper::errorSub :: The sub that warn was called from.
216              
217             - $Error::Helper::errorSubShort :: Same as errorSub, but everything prior to the subname is
218             removed. So Foo::bar would become bar.
219              
220             - $Error::Helper::errorPackage :: The package from which warn was called from.
221              
222             - $Error::Helper::errorPackageShort :: Saome as package, but everthing prior to the last item
223             in the name space is removed. So Foo::Foo::Bar would just become Bar.
224              
225             =head1 METHODS
226              
227             =head2 error
228              
229             Returns the current error code and true if there is an error.
230              
231             If there is no error, undef is returned.
232              
233             if($self->error){
234             # do something
235             }
236              
237             =cut
238              
239             sub error {
240 0     0 1   return $_[0]->{error};
241             }
242              
243             =head2 errorblank
244              
245             This blanks the error storage and is only meant for internal usage.
246              
247             It does the following.
248              
249             $self->{error} = undef;
250             $self->{errorFilename} = undef;
251             $self->{errorLine} = undef;
252             $self->{errorString} = "";
253              
254             If $self->{perror} is set, it will not be able to blank any current
255             errors.
256              
257             =cut
258              
259             sub errorblank {
260 0     0 1   my $self = $_[0];
261              
262 0 0         if ( $self->{perror} ) {
263 0           my ( $package, $filename, $line ) = caller;
264              
265             #get the calling sub
266 0           my @called = caller(1);
267 0           my $subroutine = $called[3];
268 0           $subroutine =~ s/.*\:\://g;
269              
270 0           $package =~ s/\:\:/\-/g;
271              
272 0           my $error
273             = $package . ' '
274             . $subroutine
275             . ': Unable to blank, as a permanent error is set. '
276             . 'error="'
277             . $self->error
278             . '" errorFilename="'
279             . $self->errorFilename
280             . '" errorLine="'
281             . $self->errorLine
282             . '" errorString="'
283             . $self->errorString
284             . '" file="'
285             . $filename
286             . ' line='
287             . $line;
288              
289 0 0         if ( !$self->{errorExtra}{perror_not_fatal} ) {
290 0           die($error);
291             } else {
292 0           print STDERR $error;
293             }
294              
295 0           return undef;
296             } ## end if ( $self->{perror} )
297              
298 0           $self->{error} = undef;
299 0           $self->{errorFilename} = undef;
300 0           $self->{errorLine} = undef;
301 0           $self->{errorString} = "";
302              
303 0           $error = undef;
304 0           $perror = undef;
305 0           $errorLine = undef;
306 0           $errorFilename = undef;
307 0           $errorString = '';
308 0           $errorFlag = undef;
309 0           $errorPackage = undef;
310 0           $errorPackageShort = undef;
311 0           $errorSub = undef;
312 0           $errorSubShort = undef;
313              
314 0           return 1;
315             } ## end sub errorblank
316              
317             =head2 errorFilename
318              
319             This returns the filename in which the error occured or other wise returns undef.
320              
321             if($self->error){
322             print 'error happened in '.$self->errorFilename."\n";
323             }
324              
325             =cut
326              
327             sub errorFilename {
328 0     0 1   return $_[0]->{errorFilename};
329             }
330              
331             =head2 errorFlag
332              
333             This returns the error flag for the current error.
334              
335             If none is set, undef is returned.
336              
337             This may be used in a similar manner as the error method.
338              
339             if ( $self->errorFlag ){
340             if ( $self->errorFlag eq 'foo' ){
341             # do something
342             }else{
343             die('error flag '.$self->errorFlag.' can not be handled');
344             }
345             }
346              
347             =cut
348              
349             sub errorFlag {
350 0 0   0 1   if ( !$_[0]->{error} ) {
351 0           return undef;
352             }
353              
354 0 0 0       if ( !defined( $_[0]->{errorExtra} )
      0        
      0        
      0        
355             || ref( $_[0]->{errorExtra} ) ne 'HASH'
356             || ( !defined( $_[0]->{errorExtra}{flags} ) )
357             || ref( $_[0]->{errorExtra}{flags} ) ne 'HASH'
358             || !defined( $_[0]->{errorExtra}{flags}{ $_[0]->{error} } ) )
359             {
360 0           return 'other';
361             }
362              
363 0           return $_[0]->{errorExtra}{flags}{ $_[0]->{error} };
364             } ## end sub errorFlag
365              
366             =head2 errorLine
367              
368             This returns the filename in which the error occured or other wise returns undef.
369              
370             if($self->error){
371             print 'error happened at line '.$self->errorLine."\n";
372             }
373              
374             =cut
375              
376             sub errorLine {
377 0     0 1   return $_[0]->{errorLine};
378             }
379              
380             =head2 errorString
381              
382             Returns the error string if there is one. If there is not,
383             it will return ''.
384              
385             if($self->error){
386             warn('error: '.$self->error.":".$self->errorString);
387             }
388              
389             =cut
390              
391             sub errorString {
392 0     0 1   return $_[0]->{errorString};
393             }
394              
395             =head2 perror
396              
397             This returns a Perl boolean for if there is a permanent
398             error or not.
399              
400             if($self->perror){
401             warn('A permanent error is set');
402             }
403              
404             =cut
405              
406             sub perror {
407 0     0 1   return $_[0]->{perror};
408             }
409              
410             =head2 warn
411              
412             Throws a warn like error message based using the contents of $self->errorString
413              
414             $self->warn;
415              
416             =cut
417              
418             sub warn {
419 0     0 1   my $self = $_[0];
420              
421 0           my ( $package, $filename, $line ) = caller;
422              
423 0           $errorPackage = $package;
424              
425 0           $self->{errorFilename} = $filename;
426 0           $errorFilename = $filename;
427 0           $self->{errorLine} = $line;
428 0           $errorLine = $line;
429              
430 0 0         if ( !defined( $self->{error} ) ) {
431 0           $self->{error} = 3060;
432             }
433 0           $error = $self->{error};
434              
435 0 0         if ( !defined( $self->{errorString} ) ) {
436 0           $self->{errorString} = 'unknown... warn called without errorString being set';
437             }
438 0           $errorString = $self->{errorString};
439              
440 0           $perror = $self->{perror};
441              
442 0           $errorFlag = $self->errorFlag;
443              
444             #get the calling sub
445 0           my @called = caller(1);
446 0           my $subroutine = $called[3];
447 0           $errorSub = $subroutine;
448 0           $subroutine =~ s/.*\:\://g;
449 0           $errorSubShort = $subroutine;
450              
451 0           $package =~ s/\:\:/\-/g;
452 0           $errorPackageShort = $package;
453              
454 0           my $error
455             = $package . ' '
456             . $subroutine . ':'
457             . $self->error . ':'
458             . $errorFlag . ': '
459             . $errorString
460             . ' at line '
461             . $line . ' in '
462             . $filename . "\n";
463              
464 0 0 0       if (
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
465             $self->{errorExtra}{all_fatal}
466             || (
467             $self->perror
468             && !(
469             defined( $self->{errorExtra} )
470             && ref( $self->{errorExtra} ) eq 'HASH'
471             && $self->{errorExtra}{perror_not_fatal}
472             )
473             )
474             || ( defined( $self->{errorExtra} )
475             && ref( $self->{errorExtra} ) eq 'HASH'
476             && defined( $self->{errorExtra}{fatal_errors} )
477             && ref( $self->{errorExtra}{fatal_errors} ) eq 'HASH'
478             && $self->{errorExtra}{fatal_errors}{ $self->{error} } )
479             || ( defined( $self->{errorExtra} )
480             && ref( $self->{errorExtra} ) eq 'HASH'
481             && defined( $self->{errorExtra}{fatal_flags} )
482             && ref( $self->{errorExtra}{fatal_flags} ) eq 'HASH'
483             && $self->{errorExtra}{fatal_flags}{ $self->errorFlag } )
484             )
485             {
486 0           die($error);
487             } ## end if ( $self->{errorExtra}{all_fatal} || ( $self...))
488              
489 0           print STDERR $error;
490             } ## end sub warn
491              
492             =head2 warnString
493              
494             Throws a warn like error in the same for mate as warn, but with a freeform message.
495              
496             This will not trigger any of the fatality checks. It will also not set any of the error values.
497              
498             $self->warnString('some error');
499              
500             =cut
501              
502             sub warnString {
503 0     0 1   my $self = $_[0];
504 0           my $string = $_[1];
505              
506 0 0         if ( !defined($string) ) {
507 0           $string = 'undef';
508             }
509              
510 0           my ( $package, $filename, $line ) = caller;
511              
512             #get the calling sub
513 0           my @called = caller(1);
514 0           my $subroutine = $called[3];
515 0 0         if ( defined($subroutine) ) {
516 0           $subroutine =~ s/.*\:\://g;
517 0           $package =~ s/\:\:/\-/g;
518 0           print STDERR $package . ' ' . $subroutine . ': ' . $string . ' in ' . $filename . ' at line ' . $line . "\n";
519             } else {
520 0           print STDERR $package . ': ' . $string . ' in ' . $filename . ' at line ' . $line . "\n";
521             }
522             } ## end sub warnString
523              
524             =head1 ERROR FLAGS
525              
526             Error flags are meant to be short non-spaced strings that are easier to remember than a specific error integer.
527              
528             'other' is the generic error flag for when one is not defined.
529              
530             An error flag should never evaluate to false if an error is present.
531              
532             =head1 AUTHOR
533              
534             Zane C. Bowers-Hadley, C<< >>
535              
536             =head1 BUGS
537              
538             Please report any bugs or feature requests to C, or through
539             the web interface at L. I will be notified, and then you'll
540             automatically be notified of progress on your bug as I make changes.
541              
542             =head1 SUPPORT
543              
544             You can find documentation for this module with the perldoc command.
545              
546             perldoc Error::Helper
547              
548              
549             You can also look for information at:
550              
551             =over 4
552              
553             =item * RT: CPAN's request tracker
554              
555             L
556              
557             =item * Search CPAN
558              
559            
560              
561             =back
562              
563             =head1 LICENSE AND COPYRIGHT
564              
565             Copyright 2023 Zane C. Bowers-Hadley.
566              
567             This program is free software; you can redistribute it and/or modify it
568             under the terms of either: the GNU General Public License as published
569             by the Free Software Foundation; or the Artistic License.
570              
571             See http://dev.perl.org/licenses/ for more information.
572              
573              
574             =cut
575              
576             1; # End of Error::Helper