1Exception::Class::TryCaUtscehr(3C)ontributed Perl DocumeEnxtcaetpitoinon::Class::TryCatch(3)
2
3
4
6 Exception::Class::TryCatch - Syntactic try/catch sugar for use with
7 Exception::Class
8
10 version 1.13
11
13 use Exception::Class::TryCatch;
14
15 # simple usage of catch()
16
17 eval { Exception::Class::Base->throw('error') };
18 catch my $err and warn $err->error;
19
20 # catching only certain types or else rethrowing
21
22 eval { Exception::Class::Base::SubClass->throw('error') };
23 catch( my $err, ['Exception::Class::Base', 'Other::Exception'] )
24 and warn $err->error;
25
26 # catching and handling different types of errors
27
28 eval { Exception::Class::Base->throw('error') };
29 if ( catch my $err ) {
30 $err->isa('this') and do { handle_this($err) };
31 $err->isa('that') and do { handle_that($err) };
32 }
33
34 # use "try eval" to push exceptions onto a stack to catch later
35
36 try eval {
37 Exception::Class::Base->throw('error')
38 };
39 do {
40 # cleanup that might use "try/catch" again
41 };
42 catch my $err; # catches a matching "try"
43
45 Exception::Class::TryCatch provides syntactic sugar for use with
46 Exception::Class using the familiar keywords "try" and "catch". Its
47 primary objective is to allow users to avoid dealing directly with $@
48 by ensuring that any exceptions caught in an "eval" are captured as
49 Exception::Class objects, whether they were thrown objects to begin
50 with or whether the error resulted from "die". This means that users
51 may immediately use "isa" and various Exception::Class methods to
52 process the exception.
53
54 In addition, this module provides for a method to push errors onto a
55 hidden error stack immediately after an "eval" so that cleanup code or
56 other error handling may also call "eval" without the original error in
57 $@ being lost.
58
59 Inspiration for this module is due in part to Dave Rolsky's article
60 "Exception Handling in Perl With Exception::Class" in The Perl Journal
61 (Rolsky 2004).
62
63 The "try/catch" syntax used in this module does not use code reference
64 prototypes the way the Error.pm module does, but simply provides some
65 helpful functionality when used in combination with "eval". As a
66 result, it avoids the complexity and dangers involving nested closures
67 and memory leaks inherent in Error.pm (Perrin 2003).
68
69 Rolsky (2004) notes that these memory leaks may not occur in recent
70 versions of Perl, but the approach used in Exception::Class::TryCatch
71 should be safe for all versions of Perl as it leaves all code execution
72 to the "eval" in the current scope, avoiding closures altogether.
73
75 "catch"
76 # zero argument form
77 my $err = catch;
78
79 # one argument forms
80 catch my $err;
81 my $err = catch( [ 'Exception::Type', 'Exception::Other::Type' ] );
82
83 # two argument form
84 catch my $err, [ 'Exception::Type', 'Exception::Other::Type' ];
85
86 Returns an "Exception::Class::Base" object (or an object which is a
87 subclass of it) if an exception has been caught by "eval". If no
88 exception was thrown, it returns "undef" in scalar context and an empty
89 list in list context. The exception is either popped from a hidden
90 error stack (see "try") or, if the stack is empty, taken from the
91 current value of $@.
92
93 If the exception is not an "Exception::Class::Base" object (or subclass
94 object), an "Exception::Class::Base" object will be created using the
95 string contents of the exception. This means that calls to "die" will
96 be wrapped and may be treated as exception objects. Other objects
97 caught will be stringified and wrapped likewise. Such wrapping will
98 likely result in confusing stack traces and the like, so any methods
99 other than "error" used on "Exception::Class::Base" objects caught
100 should be used with caution.
101
102 "catch" is prototyped to take up to two optional scalar arguments. The
103 single argument form has two variations.
104
105 • If the argument is a reference to an array, any exception caught
106 that is not of the same type (or a subtype) of one of the classes
107 listed in the array will be rethrown.
108
109 • If the argument is not a reference to an array, "catch" will set
110 the argument to the same value that is returned. This allows for
111 the "catch my $err" idiom without parentheses.
112
113 In the two-argument form, the first argument is set to the same value
114 as is returned. The second argument must be an array reference and is
115 handled the same as as for the single argument version with an array
116 reference, as given above.
117
118 "caught" (DEPRECATED)
119 "caught" is a synonym for "catch" for syntactic convenience.
120
121 NOTE: Exception::Class version 1.21 added a "caught" method of its own.
122 It provides somewhat similar functionality to this subroutine, but with
123 very different semantics. As this class is intended to work closely
124 with Exception::Class, the existence of a subroutine and a method with
125 the same name is liable to cause confusion and this method is
126 deprecated and may be removed in future releases of
127 Exception::Class::TryCatch.
128
129 This method is no longer exported by default.
130
131 "try"
132 # void context
133 try eval {
134 # dangerous code
135 };
136 do {
137 # cleanup code can use try/catch
138 };
139 catch my $err;
140
141 # scalar context
142 $rv = try eval { return $scalar };
143
144 # list context
145 @rv = try [ eval { return @array } ];
146
147 Pushes the current error ($@) onto a hidden error stack for later use
148 by "catch". "try" uses a prototype that expects a single scalar so
149 that it can be used with eval without parentheses. As "eval { BLOCK }"
150 is an argument to try, it will be evaluated just prior to "try",
151 ensuring that "try" captures the correct error status. "try" does not
152 itself handle any errors -- it merely records the results of "eval".
153 "try { BLOCK }" will be interpreted as passing a hash reference and
154 will (probably) not compile. (And if it does, it will result in very
155 unexpected behavior.)
156
157 Since "try" requires a single argument, "eval" will normally be called
158 in scalar context. To use "eval" in list context with "try", put the
159 call to "eval" in an anonymous array:
160
161 @rv = try [ eval {return @array} ];
162
163 When "try" is called in list context, if the argument to "try" is an
164 array reference, "try" will dereference the array and return the
165 resulting list.
166
167 In scalar context, "try" passes through the scalar value returned by
168 "eval" without modifications -- even if that is an array reference.
169
170 $rv = try eval { return $scalar };
171 $rv = try eval { return [ qw( anonymous array ) ] };
172
173 Of course, if the eval throws an exception, "eval" and thus "try" will
174 return undef.
175
176 "try" must always be properly bracketed with a matching "catch" or
177 unexpected behavior may result when "catch" pops the error off of the
178 stack. "try" executes right after its "eval", so inconsistent usage of
179 "try" like the following will work as expected:
180
181 try eval {
182 eval { die "inner" };
183 catch my $inner_err
184 die "outer" if $inner_err;
185 };
186 catch my $outer_err;
187 # handle $outer_err;
188
189 However, the following code is a problem:
190
191 # BAD EXAMPLE
192 try eval {
193 try eval { die "inner" };
194 die $@ if $@;
195 };
196 catch my $outer_err;
197 # handle $outer_err;
198
199 This code will appear to run correctly, but "catch" gets the exception
200 from the inner "try", not the outer one, and there will still be an
201 exception on the error stack which will be caught by the next "catch"
202 in the program, causing unexpected (and likely hard to track) behavior.
203
204 In short, if you use "try", you must have a matching "catch". The
205 problem code above should be rewritten as:
206
207 try eval {
208 try eval { die "inner" };
209 catch my $inner_err;
210 $inner_err->rethrow if $inner_err;
211 };
212 catch my $outer_err;
213 # handle $outer_err;
214
216 1. perrin. (2003), "Re: Re2: Learning how to use the Error module by
217 example", (perlmonks.org), Available:
218 http://www.perlmonks.org/index.pl?node_id=278900 (Accessed
219 September 8, 2004).
220
221 2. Rolsky, D. (2004), "Exception Handling in Perl with
222 Exception::Class", The Perl Journal, vol. 8, no. 7, pp. 9-13
223
225 • Exception::Class
226
227 • Error -- but see (Perrin 2003) before using
228
230 Bugs / Feature Requests
231 Please report any bugs or feature requests through the issue tracker at
232 <https://github.com/dagolden/Exception-Class-TryCatch/issues>. You
233 will be notified automatically of any progress on your issue.
234
235 Source Code
236 This is open source software. The code repository is available for
237 public review and contribution under the terms of the license.
238
239 <https://github.com/dagolden/Exception-Class-TryCatch>
240
241 git clone https://github.com/dagolden/Exception-Class-TryCatch.git
242
244 David Golden <dagolden@cpan.org>
245
247 This software is Copyright (c) 2014 by David Golden.
248
249 This is free software, licensed under:
250
251 The Apache License, Version 2.0, January 2004
252
253
254
255perl v5.36.0 2023-01-20 Exception::Class::TryCatch(3)