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