File Coverage

lib/Workflow/Exception.pm
Criterion Covered Total %
statement 42 42 100.0
branch 2 2 100.0
condition n/a
subroutine 13 13 100.0
pod 6 6 100.0
total 63 63 100.0


line stmt bran cond sub pod time code
1             package Workflow::Exception;
2              
3 29     29   10880 use warnings;
  29         56  
  29         1275  
4 29     29   188 use strict;
  29         70  
  29         1907  
5              
6             # Declare some of our exceptions...
7              
8             use Exception::Class (
9 29         701 'Workflow::Exception::Condition' => {
10             isa => 'Workflow::Exception',
11             description => 'Condition failed errors',
12             },
13             'Workflow::Exception::Configuration' => {
14             isa => 'Workflow::Exception',
15             description => 'Configuration errors',
16             },
17             'Workflow::Exception::Persist' => {
18             isa => 'Workflow::Exception',
19             description => 'Persistence errors',
20             },
21             'Workflow::Exception::Validation' => {
22             isa => 'Workflow::Exception',
23             description => 'Validation errors',
24             fields => 'invalid_fields',
25             },
26 29     29   1757 );
  29         26490  
27              
28 29     29   41094 use Log::Log4perl qw( get_logger );
  29         91  
  29         198  
29 29     29   1754 use Log::Log4perl::Level;
  29         58  
  29         303  
30              
31             my %TYPE_CLASSES = (
32             condition_error => 'Workflow::Exception::Condition',
33             configuration_error => 'Workflow::Exception::Configuration',
34             persist_error => 'Workflow::Exception::Persist',
35             validation_error => 'Workflow::Exception::Validation',
36             workflow_error => 'Workflow::Exception',
37             );
38             my %TYPE_LOGGING = (
39             condition_error => $TRACE,
40             configuration_error => $ERROR,
41             persist_error => $ERROR,
42             validation_error => $INFO,
43             workflow_error => $ERROR,
44             );
45              
46              
47             $Workflow::Exception::VERSION = '1.62';
48             @Workflow::Exception::ISA = qw( Exporter Exception::Class::Base );
49             @Workflow::Exception::EXPORT_OK = keys %TYPE_CLASSES;
50              
51             # Exported shortcuts
52              
53             sub _mythrow {
54 118     118   316 my ( $type, @items ) = @_;
55              
56 118         265 my ( $msg, %params ) = _massage(@items);
57 118         326 my $caller = caller;
58 118         1815 my $log = get_logger($caller); # log as if part of the package of the caller
59 118         8742 my ( $pkg, $line ) = (caller)[ 0, 2 ];
60 118         1865 my ( $prev_pkg, $prev_line ) = ( caller 1 )[ 0, 2 ];
61              
62             # Do not log condition errors
63 118         2151 $log->log( $TYPE_LOGGING{$type},
64             "$type exception thrown from [$pkg: $line; before: ",
65             "$prev_pkg: $prev_line]: $msg" );
66              
67             goto &Exception::Class::Base::throw(
68 118         11219 $TYPE_CLASSES{$type},
69             message => $msg,
70             %params
71             );
72             }
73              
74             # Use 'goto' here to maintain the stack trace
75              
76             sub condition_error {
77 91     91 1 9614 unshift @_, 'condition_error';
78 91         298 goto &_mythrow;
79             }
80              
81             sub configuration_error {
82 11     11 1 2330 unshift @_, 'configuration_error';
83 11         41 goto &_mythrow;
84             }
85              
86             sub persist_error {
87 6     6 1 2224 unshift @_, 'persist_error';
88 6         15 goto &_mythrow;
89             }
90              
91             sub validation_error {
92 4     4 1 1449 unshift @_, 'validation_error';
93 4         14 goto &_mythrow;
94             }
95              
96             sub workflow_error {
97 6     6 1 1185 unshift @_, 'workflow_error';
98 6         140 goto &_mythrow;
99             }
100              
101             # Override 'throw' so we can massage the message and parameters into
102             # the right format for E::C
103              
104             sub throw {
105 1     1 1 2460 my ( $class, @items ) = @_;
106              
107 1         28 my ( $msg, %params ) = _massage(@items);
108 1         5 goto &Exception::Class::Base::throw( $class, message => $msg, %params );
109             }
110              
111             sub _massage {
112 119     119   242 my @items = @_;
113              
114 119 100       315 my %params = ( ref $items[-1] eq 'HASH' ) ? %{ pop @items } : ();
  1         3  
115 119         297 my $msg = join '', @items;
116 119         439 $msg =~ s/\\n/ /g; # don't log newlines as per Log4perl recommendations
117 119         406 return ( $msg, %params );
118             }
119              
120             1;
121              
122             __END__
123              
124             =pod
125              
126             =head1 NAME
127              
128             Workflow::Exception - Base class for workflow exceptions
129              
130             =head1 VERSION
131              
132             This documentation describes version 1.62 of this package
133              
134             =head1 SYNOPSIS
135              
136             # Standard usage
137             use Workflow::Exception qw( workflow_error );
138              
139             my $user = $wf->context->param( 'current_user' );
140             unless ( $user->check_password( $entered_password ) ) {
141             workflow_error "User exists but password check failed";
142             }
143              
144             # Pass a list of strings to form the message
145              
146             unless ( $user->check_password( $entered_password ) ) {
147             workflow_error 'Bad login: ', $object->login_attempted;
148             }
149              
150             # Using other exported shortcuts
151              
152             use Workflow::Exception qw( configuration_error );
153             configuration_error "Field 'foo' must be a set to 'bar'";
154              
155             use Workflow::Exception qw( validation_error );
156             validation_error "Validation for field 'foo' failed: $error";
157              
158             =head1 DESCRIPTION
159              
160             First, you should probably look at
161             L<Exception::Class|Exception::Class> for more usage examples, why we
162             use exceptions, what they are intended for, etc.
163              
164             This is the base class for all workflow exceptions. It declares a
165             handful of exceptions and provides shortcuts to make raising an
166             exception easier and more readable.
167              
168             =head1 METHODS
169              
170             =head3 throw( @msg, [ \%params ])
171              
172             This overrides B<throw()> from L<Exception::Class|Exception::Class> to
173             add a little syntactic sugar. Instead of:
174              
175             $exception_class->throw( message => 'This is my very long error message that I would like to pass',
176             param1 => 'Param1 value',
177             param2 => 'Param2 value' );
178              
179             You can use:
180              
181             $exception_class->throw( 'This is my very long error message ',
182             'that I would like to pass',
183             { param1 => 'Param1 value',
184             param2 => 'Param2 value' } );
185              
186             And everything will work the same. Combined with the L<SHORTCUTS> this
187             makes for very readable code:
188              
189             workflow_error "Something went horribly, terribly, dreadfully, "
190             "frightfully wrong: $@",
191             { foo => 'bar' };
192              
193             =head3 condition_error
194              
195             This method transforms the error to a condition error.
196              
197             This exception is thrown via </mythrow> when a condition of a workflow is invalid.
198              
199             =head3 configuration_error
200              
201             This method transforms the error to a configuration error.
202              
203             This exception is thrown via </mythrow> when configuration of a workflow is unsuccessful.
204              
205             =head3 persist_error
206              
207             This method transforms the error to a persistance error.
208              
209             This exception is thrown via </mythrow> when the save of a workflow is unsuccessful.
210              
211             =head3 validation_error
212              
213             This method transforms the error to a validation error.
214              
215             This exception is thrown via </mythrow> when input data or similar of a workflow is unsuccessful.
216              
217             =head3 workflow_error
218              
219             This method transforms the error to a workflow error.
220              
221             This exception is thrown via </mythrow> when input data or similar of a workflow is unsuccessful.
222              
223             =head1 SHORTCUTS
224              
225             =over
226              
227             =item * B<Workflow::Exception> - import using C<workflow_error>
228              
229             =item * B<Workflow::Exception::Condition> - import using C<condition_error>
230              
231             =item * B<Workflow::Exception::Configuration> - import using C<configuration_error>
232              
233             =item * B<Workflow::Exception::Persist> - import using C<persist_error>
234              
235             =item * B<Workflow::Exception::Validation> - import using C<validation_error>
236              
237             =back
238              
239             =head1 SEE ALSO
240              
241             =over
242              
243             =item * L<Exception::Class|Exception::Class>
244              
245             =back
246              
247             =head1 COPYRIGHT
248              
249             Copyright (c) 2003-2023 Chris Winters. All rights reserved.
250              
251             This library is free software; you can redistribute it and/or modify
252             it under the same terms as Perl itself.
253              
254             Please see the F<LICENSE>
255              
256             =head1 AUTHORS
257              
258             Please see L<Workflow>
259              
260             =cut