Commit | Line | Data |
3176feef |
1 | package Try::Tiny; |
2 | |
3 | use strict; |
ae53da51 |
4 | #use warnings; |
3176feef |
5 | |
ae53da51 |
6 | use vars qw(@EXPORT @EXPORT_OK $VERSION @ISA); |
7 | |
8 | BEGIN { |
9 | require Exporter; |
10 | @ISA = qw(Exporter); |
11 | } |
3176feef |
12 | |
7c33c026 |
13 | $VERSION = "0.02"; |
3176feef |
14 | |
15 | $VERSION = eval $VERSION; |
16 | |
17 | @EXPORT = @EXPORT_OK = qw(try catch); |
18 | |
6f114080 |
19 | $Carp::Internal{+__PACKAGE__}++; |
20 | |
3176feef |
21 | sub try (&;$) { |
22 | my ( $try, $catch ) = @_; |
23 | |
24 | # we need to save this here, the eval block will be in scalar context due |
25 | # to $failed |
26 | my $wantarray = wantarray; |
27 | |
1d64c1ad |
28 | # save the value of $@ so we can set $@ back to it in the beginning of the eval |
511c05ca |
29 | my $prev_error = $@; |
30 | |
3176feef |
31 | my ( @ret, $error, $failed ); |
32 | |
1d64c1ad |
33 | # FIXME consider using local $SIG{__DIE__} to accumulate all errors. It's |
3176feef |
34 | # not perfect, but we could provide a list of additional errors for |
35 | # $catch->(); |
36 | |
37 | { |
38 | # localize $@ to prevent clobbering of previous value by a successful |
39 | # eval. |
40 | local $@; |
41 | |
42 | # failed will be true if the eval dies, because 1 will not be returned |
43 | # from the eval body |
44 | $failed = not eval { |
511c05ca |
45 | $@ = $prev_error; |
3176feef |
46 | |
47 | # evaluate the try block in the correct context |
48 | if ( $wantarray ) { |
49 | @ret = $try->(); |
50 | } elsif ( defined $wantarray ) { |
51 | $ret[0] = $try->(); |
52 | } else { |
53 | $try->(); |
54 | }; |
55 | |
56 | return 1; # properly set $fail to false |
57 | }; |
58 | |
1d64c1ad |
59 | # copy $@ to $error; when we leave this scope, local $@ will revert $@ |
3176feef |
60 | # back to its previous value |
61 | $error = $@; |
62 | } |
63 | |
1d64c1ad |
64 | # at this point $failed contains a true value if the eval died, even if some |
65 | # destructor overwrote $@ as the eval was unwinding. |
3176feef |
66 | if ( $failed ) { |
67 | # if we got an error, invoke the catch block. |
68 | if ( $catch ) { |
69 | # This works like given($error), but is backwards compatible and |
70 | # sets $_ in the dynamic scope for the body of C<$catch> |
71 | for ($error) { |
72 | return $catch->($error); |
73 | } |
44599111 |
74 | |
75 | # in case when() was used without an explicit return, the C<for> |
76 | # loop will be aborted and there's no useful return value |
3176feef |
77 | } |
44599111 |
78 | |
79 | return; |
3176feef |
80 | } else { |
81 | # no failure, $@ is back to what it was, everything is fine |
82 | return $wantarray ? @ret : $ret[0]; |
83 | } |
84 | } |
85 | |
86 | sub catch (&) { |
87 | return $_[0]; |
88 | } |
89 | |
90 | |
91 | __PACKAGE__ |
92 | |
93 | __END__ |
94 | |
95 | =pod |
96 | |
97 | =head1 NAME |
98 | |
99 | Try::Tiny - minimal try/catch with proper localization of $@ |
100 | |
101 | =head1 SYNOPSIS |
102 | |
103 | # handle errors with a catch handler |
104 | try { |
105 | die "foo"; |
106 | } catch { |
107 | warn "caught error: $_"; |
108 | }; |
109 | |
110 | # just silence errors |
111 | try { |
112 | die "foo"; |
113 | }; |
114 | |
115 | =head1 DESCRIPTION |
116 | |
117 | This module provides bare bones C<try>/C<catch> statements that are designed to |
1f7c5af6 |
118 | minimize common mistakes with eval blocks, and NOTHING else. |
3176feef |
119 | |
120 | This is unlike L<TryCatch> which provides a nice syntax and avoids adding |
121 | another call stack layer, and supports calling C<return> from the try block to |
122 | return from the parent subroutine. These extra features come at a cost of a few |
123 | dependencies, namely L<Devel::Declare> and L<Scope::Upper> which are |
1f7c5af6 |
124 | occasionally problematic, and the additional catch filtering uses L<Moose> |
125 | type constraints which may not be desirable either. |
3176feef |
126 | |
1f7c5af6 |
127 | The main focus of this module is to provide simple and reliable error handling |
3176feef |
128 | for those having a hard time installing L<TryCatch>, but who still want to |
129 | write correct C<eval> blocks without 5 lines of boilerplate each time. |
130 | |
131 | It's designed to work as correctly as possible in light of the various |
132 | pathological edge cases (see L<BACKGROUND>) and to be compatible with any style |
133 | of error values (simple strings, references, objects, overloaded objects, etc). |
134 | |
a5cd5f73 |
135 | If the try block dies, it returns the value of the last statement executed in |
136 | the catch block, if there is one. Otherwise, it returns C<undef> in scalar |
137 | context or the empty list in list context. The following two examples both |
138 | assign C<"bar"> to C<$x>. |
139 | |
140 | my $x = try { die "foo" } catch { "bar" }; |
141 | |
142 | my $x = eval { die "foo" } || "bar"; |
143 | |
3176feef |
144 | =head1 EXPORTS |
145 | |
1f7c5af6 |
146 | All functions are exported by default using L<Exporter>. |
3176feef |
147 | |
6157bcb8 |
148 | If you need to rename the C<try> or C<catch> keyword consider using |
149 | L<Sub::Import> to get L<Sub::Exporter>'s flexibility. |
3176feef |
150 | |
151 | =over 4 |
152 | |
1f7c5af6 |
153 | =item try (&;$) |
3176feef |
154 | |
1f7c5af6 |
155 | Takes one mandatory try subroutine and one optional catch subroutine. |
3176feef |
156 | |
157 | The mandatory subroutine is evaluated in the context of an C<eval> block. |
158 | |
1f7c5af6 |
159 | If no error occurred the value from the first block is returned, preserving |
160 | list/scalar context. |
3176feef |
161 | |
162 | If there was an error and the second subroutine was given it will be invoked |
163 | with the error in C<$_> (localized) and as that block's first and only |
164 | argument. |
165 | |
1f7c5af6 |
166 | Note that the error may be false, but if that happens the C<catch> block will |
1d64c1ad |
167 | still be invoked. |
3176feef |
168 | |
1f7c5af6 |
169 | =item catch (&) |
170 | |
171 | Intended to be used in the second argument position of C<try>. |
3176feef |
172 | |
a717a876 |
173 | Just returns the subroutine it was given. |
3176feef |
174 | |
175 | catch { ... } |
176 | |
177 | is the same as |
178 | |
179 | sub { ... } |
180 | |
ac4f5f9f |
181 | Inside the catch block the previous value of C<$@> is still available for use. |
1d64c1ad |
182 | This value may or may not be meaningful depending on what happened before the |
ac4f5f9f |
183 | C<try>, but it might be a good idea to preserve it in an error stack. |
184 | |
3176feef |
185 | =back |
186 | |
187 | =head1 BACKGROUND |
188 | |
189 | There are a number of issues with C<eval>. |
190 | |
191 | =head2 Clobbering $@ |
192 | |
193 | When you run an eval block and it succeeds, C<$@> will be cleared, potentially |
a717a876 |
194 | clobbering an error that is currently being caught. |
3176feef |
195 | |
1f7c5af6 |
196 | This causes action at a distance, clearing previous errors your caller may have |
197 | not yet handled. |
198 | |
199 | C<$@> must be properly localized before invoking C<eval> in order to avoid this |
200 | issue. |
3176feef |
201 | |
511c05ca |
202 | More specifically, C<$@> is clobbered at the begining of the C<eval>, which |
203 | also makes it impossible to capture the previous error before you die (for |
204 | instance when making exception objects with error stacks). |
205 | |
206 | For this reason C<try> will actually set C<$@> to its previous value (before |
1d64c1ad |
207 | the localization) in the beginning of the C<eval> block. |
511c05ca |
208 | |
3176feef |
209 | =head2 Localizing $@ silently masks errors |
210 | |
211 | Inside an eval block C<die> behaves sort of like: |
212 | |
213 | sub die { |
91254b51 |
214 | $@ = $_[0]; |
3176feef |
215 | return_undef_from_eval(); |
216 | } |
217 | |
218 | This means that if you were polite and localized C<$@> you can't die in that |
1f7c5af6 |
219 | scope, or your error will be discarded (printing "Something's wrong" instead). |
3176feef |
220 | |
221 | The workaround is very ugly: |
222 | |
223 | my $error = do { |
224 | local $@; |
225 | eval { ... }; |
226 | $@; |
227 | }; |
228 | |
229 | ... |
230 | die $error; |
231 | |
232 | =head2 $@ might not be a true value |
233 | |
234 | This code is wrong: |
235 | |
236 | if ( $@ ) { |
237 | ... |
238 | } |
239 | |
1f7c5af6 |
240 | because due to the previous caveats it may have been unset. |
241 | |
1d64c1ad |
242 | C<$@> could also be an overloaded error object that evaluates to false, but |
243 | that's asking for trouble anyway. |
3176feef |
244 | |
245 | The classic failure mode is: |
246 | |
247 | sub Object::DESTROY { |
248 | eval { ... } |
249 | } |
250 | |
251 | eval { |
252 | my $obj = Object->new; |
253 | |
254 | die "foo"; |
255 | }; |
256 | |
257 | if ( $@ ) { |
258 | |
259 | } |
260 | |
1f7c5af6 |
261 | In this case since C<Object::DESTROY> is not localizing C<$@> but still uses |
1d64c1ad |
262 | C<eval>, it will set C<$@> to C<"">. |
3176feef |
263 | |
1f7c5af6 |
264 | The destructor is called when the stack is unwound, after C<die> sets C<$@> to |
3176feef |
265 | C<"foo at Foo.pm line 42\n">, so by the time C<if ( $@ )> is evaluated it has |
1f7c5af6 |
266 | been cleared by C<eval> in the destructor. |
3176feef |
267 | |
1f7c5af6 |
268 | The workaround for this is even uglier than the previous ones. Even though we |
269 | can't save the value of C<$@> from code that doesn't localize, we can at least |
270 | be sure the eval was aborted due to an error: |
3176feef |
271 | |
272 | my $failed = not eval { |
273 | ... |
274 | |
275 | return 1; |
276 | }; |
277 | |
1f7c5af6 |
278 | This is because an C<eval> that caught a C<die> will always return a false |
279 | value. |
3176feef |
280 | |
f9b91e2c |
281 | =head1 SHINY SYNTAX |
3176feef |
282 | |
1f7c5af6 |
283 | Using Perl 5.10 you can use L<perlsyn/"Switch statements">. |
3176feef |
284 | |
1f7c5af6 |
285 | The C<catch> block is invoked in a topicalizer context (like a C<given> block), |
286 | but note that you can't return a useful value from C<catch> using the C<when> |
27293e40 |
287 | blocks without an explicit C<return>. |
3176feef |
288 | |
289 | This is somewhat similar to Perl 6's C<CATCH> blocks. You can use it to |
290 | concisely match errors: |
291 | |
292 | try { |
293 | require Foo; |
294 | } catch { |
1f7c5af6 |
295 | when (/^Can't locate .*?\.pm in \@INC/) { } # ignore |
3176feef |
296 | default { die $_ } |
deb85b37 |
297 | }; |
3176feef |
298 | |
299 | =head1 CAVEATS |
300 | |
301 | =over 4 |
302 | |
303 | =item * |
304 | |
318cb1eb |
305 | C<@_> is not available, you need to name your args: |
306 | |
307 | sub foo { |
308 | my ( $self, @args ) = @_; |
309 | try { $self->bar(@args) } |
310 | } |
311 | |
312 | =item * |
313 | |
314 | C<return> returns from the C<try> block, not from the parent sub (note that |
315 | this is also how C<eval> works, but not how L<TryCatch> works): |
316 | |
317 | sub bar { |
318 | try { return "foo" }; |
319 | return "baz"; |
320 | } |
321 | |
322 | say bar(); # "baz" |
323 | |
324 | =item * |
325 | |
1f7c5af6 |
326 | C<try> introduces another caller stack frame. L<Sub::Uplevel> is not used. L<Carp> |
327 | will report this when using full stack traces. This lack of magic is considered |
328 | a feature. |
3176feef |
329 | |
330 | =item * |
331 | |
57c50f41 |
332 | The value of C<$_> in the C<catch> block is not guaranteed to be the value of |
333 | the exception thrown (C<$@>) in the C<try> block. There is no safe way to |
334 | ensure this, since C<eval> may be used unhygenically in destructors. The only |
335 | guarantee is that the C<catch> will be called if an exception is thrown. |
3176feef |
336 | |
a5cd5f73 |
337 | =item * |
338 | |
339 | The return value of the C<catch> block is not ignored, so if testing the result |
340 | of the expression for truth on success, be sure to return a false value from |
341 | the C<catch> block: |
342 | |
343 | my $obj = try { |
344 | MightFail->new; |
345 | } catch { |
346 | ... |
347 | |
348 | return; # avoid returning a true value; |
349 | }; |
350 | |
351 | return unless $obj; |
352 | |
3176feef |
353 | =back |
354 | |
355 | =head1 SEE ALSO |
356 | |
357 | =over 4 |
358 | |
359 | =item L<TryCatch> |
360 | |
361 | Much more feature complete, more convenient semantics, but at the cost of |
362 | implementation complexity. |
363 | |
9bc603cb |
364 | =item L<autodie> |
365 | |
366 | Automatic error throwing for builtin functions and more. Also designed to |
367 | work well with C<given>/C<when>. |
368 | |
f8227e43 |
369 | =item L<Throwable> |
370 | |
371 | A lightweight role for rolling your own exception classes. |
372 | |
3176feef |
373 | =item L<Error> |
374 | |
375 | Exception object implementation with a C<try> statement. Does not localize |
376 | C<$@>. |
377 | |
378 | =item L<Exception::Class::TryCatch> |
379 | |
380 | Provides a C<catch> statement, but properly calling C<eval> is your |
381 | responsibility. |
382 | |
383 | The C<try> keyword pushes C<$@> onto an error stack, avoiding some of the |
1d64c1ad |
384 | issues with C<$@>, but you still need to localize to prevent clobbering. |
3176feef |
385 | |
386 | =back |
387 | |
faecd5a0 |
388 | =head1 LIGHTNING TALK |
389 | |
390 | I gave a lightning talk about this module, you can see the slides (Firefox |
391 | only): |
392 | |
393 | L<http://nothingmuch.woobling.org/talks/takahashi.xul?data=try_tiny.txt> |
394 | |
395 | Or read the source: |
396 | |
397 | L<http://nothingmuch.woobling.org/talks/yapc_asia_2009/try_tiny.yml> |
398 | |
3176feef |
399 | =head1 VERSION CONTROL |
400 | |
401 | L<http://github.com/nothingmuch/try-tiny/> |
402 | |
403 | =head1 AUTHOR |
404 | |
405 | Yuval Kogman E<lt>nothingmuch@woobling.orgE<gt> |
406 | |
407 | =head1 COPYRIGHT |
408 | |
c4e1eb12 |
409 | Copyright (c) 2009 Yuval Kogman. All rights reserved. |
3176feef |
410 | This program is free software; you can redistribute |
c4e1eb12 |
411 | it and/or modify it under the terms of the MIT license. |
3176feef |
412 | |
413 | =cut |
414 | |