6 use vars qw(@EXPORT @EXPORT_OK $VERSION @ISA);
15 $VERSION = eval $VERSION;
17 @EXPORT = @EXPORT_OK = qw(try catch);
20 my ( $try, $catch ) = @_;
22 # we need to save this here, the eval block will be in scalar context due
24 my $wantarray = wantarray;
26 my ( @ret, $error, $failed );
28 # FIXME consider using local $SIG{__DIE__} to accumilate all errors. It's
29 # not perfect, but we could provide a list of additional errors for
33 # localize $@ to prevent clobbering of previous value by a successful
37 # failed will be true if the eval dies, because 1 will not be returned
41 # evaluate the try block in the correct context
44 } elsif ( defined $wantarray ) {
50 return 1; # properly set $fail to false
53 # copy $@ to $error, when we leave this scope local $@ will revert $@
54 # back to its previous value
58 # at this point $failed contains a true value if the eval died even if some
59 # destructor overwrite $@ as the eval was unwinding.
61 # if we got an error, invoke the catch block.
63 # This works like given($error), but is backwards compatible and
64 # sets $_ in the dynamic scope for the body of C<$catch>
66 return $catch->($error);
69 # in case when() was used without an explicit return, the C<for>
70 # loop will be aborted and there's no useful return value
75 # no failure, $@ is back to what it was, everything is fine
76 return $wantarray ? @ret : $ret[0];
93 Try::Tiny - minimal try/catch with proper localization of $@
97 # handle errors with a catch handler
101 warn "caught error: $_";
104 # just silence errors
111 This module provides bare bones C<try>/C<catch> statements that are designed to
112 minimize common mistakes with eval blocks, and NOTHING else.
114 This is unlike L<TryCatch> which provides a nice syntax and avoids adding
115 another call stack layer, and supports calling C<return> from the try block to
116 return from the parent subroutine. These extra features come at a cost of a few
117 dependencies, namely L<Devel::Declare> and L<Scope::Upper> which are
118 occasionally problematic, and the additional catch filtering uses L<Moose>
119 type constraints which may not be desirable either.
121 The main focus of this module is to provide simple and reliable error handling
122 for those having a hard time installing L<TryCatch>, but who still want to
123 write correct C<eval> blocks without 5 lines of boilerplate each time.
125 It's designed to work as correctly as possible in light of the various
126 pathological edge cases (see L<BACKGROUND>) and to be compatible with any style
127 of error values (simple strings, references, objects, overloaded objects, etc).
131 All functions are exported by default using L<Exporter>.
133 In the future L<Sub::Exporter> may be used to allow the keywords to be renamed,
134 but this technically does not satisfy Adam Kennedy's definition of "Tiny".
140 Takes one mandatory try subroutine and one optional catch subroutine.
142 The mandatory subroutine is evaluated in the context of an C<eval> block.
144 If no error occurred the value from the first block is returned, preserving
147 If there was an error and the second subroutine was given it will be invoked
148 with the error in C<$_> (localized) and as that block's first and only
151 Note that the error may be false, but if that happens the C<catch> block will
156 Intended to be used in the second argument position of C<try>.
158 Just returns the subroutine it was given.
170 There are a number of issues with C<eval>.
174 When you run an eval block and it succeeds, C<$@> will be cleared, potentially
175 clobbering an error that is currently being caught.
177 This causes action at a distance, clearing previous errors your caller may have
180 C<$@> must be properly localized before invoking C<eval> in order to avoid this
183 =head2 Localizing $@ silently masks errors
185 Inside an eval block C<die> behaves sort of like:
189 return_undef_from_eval();
192 This means that if you were polite and localized C<$@> you can't die in that
193 scope, or your error will be discarded (printing "Something's wrong" instead).
195 The workaround is very ugly:
206 =head2 $@ might not be a true value
214 because due to the previous caveats it may have been unset.
216 C<$@> could also an overloaded error object that evaluates to false, but that's
217 asking for trouble anyway.
219 The classic failure mode is:
221 sub Object::DESTROY {
226 my $obj = Object->new;
235 In this case since C<Object::DESTROY> is not localizing C<$@> but still uses
236 C<eval> it will set C<$@> to C<"">.
238 The destructor is called when the stack is unwound, after C<die> sets C<$@> to
239 C<"foo at Foo.pm line 42\n">, so by the time C<if ( $@ )> is evaluated it has
240 been cleared by C<eval> in the destructor.
242 The workaround for this is even uglier than the previous ones. Even though we
243 can't save the value of C<$@> from code that doesn't localize, we can at least
244 be sure the eval was aborted due to an error:
246 my $failed = not eval {
252 This is because an C<eval> that caught a C<die> will always return a false
257 Using Perl 5.10 you can use L<perlsyn/"Switch statements">.
259 The C<catch> block is invoked in a topicalizer context (like a C<given> block),
260 but note that you can't return a useful value from C<catch> using the C<when>
261 blocks without an explicit C<return>.
263 This is somewhat similar to Perl 6's C<CATCH> blocks. You can use it to
264 concisely match errors:
269 when (/^Can't locate .*?\.pm in \@INC/) { } # ignore
279 C<try> introduces another caller stack frame. L<Sub::Uplevel> is not used. L<Carp>
280 will report this when using full stack traces. This lack of magic is considered
285 The value of C<$_> in the C<catch> block is not guaranteed to be preserved,
286 there is no safe way to ensure this if C<eval> is used unhygenically in
287 destructors. It's only guaranteeed that the C<catch> will be called.
297 Much more feature complete, more convenient semantics, but at the cost of
298 implementation complexity.
302 A lightweight role for rolling your own exception classes.
306 Exception object implementation with a C<try> statement. Does not localize
309 =item L<Exception::Class::TryCatch>
311 Provides a C<catch> statement, but properly calling C<eval> is your
314 The C<try> keyword pushes C<$@> onto an error stack, avoiding some of the
315 issues with C<$@> but you still need to localize to prevent clobbering.
319 =head1 VERSION CONTROL
321 L<http://github.com/nothingmuch/try-tiny/>
325 Yuval Kogman E<lt>nothingmuch@woobling.orgE<gt>
329 Copyright (c) 2009 Yuval Kogman. All rights reserved.
330 This program is free software; you can redistribute
331 it and/or modify it under the terms of the MIT license.