Is it possible to use Try::Tiny in a Perl program that has a 'overloaded' $SIG{__DIE__}
?
For example, the desired output of this program would be "caught it":
#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;
use Try::Tiny;
# here how to deal with try and catch
$SIG{__DIE__} =
sub {
print "died my way $_[0]"
};
my $rv;
try {die "its only a flesh wound"; }
catch {
$rv = undef;
print "caught it: $_ ";
};
Thanks for looking and any advice!
The docs for $SIG{__DIE__}
show $^S
being used for a reason: You almost always want to use $^S
in __DIE__
handlers to avoid the problem you are asking about.
For example,
#!/usr/bin/perl
use strict;
use warnings;
use Try::Tiny;
$SIG{__DIE__} = sub {
return if $^S; # If in eval.
print(STDERR "Died: $_[0]"); # Send msg to STDERR, not STDOUT.
exit( $! || ( $? >> 8 ) || 255 ); # Emulate die().
};
try {
die("It's only a flesh wound.");
} catch {
print("Caught: $_");
};
die("More than a flesh wound");
print("done.\n");
outputs
Caught: It's only a flesh wound. at a.pl line 14.
Died: More than a flesh wound at a.pl line 19.
Try::Tiny
is mostly a syntactic sugar wrapper for an eval
call, and a die
call inside an eval
block will call a $SIG{__DIE__}
handler. The authors anticipated your objection, but ultimately decided to stick with the legacy behavior.
Though it can be argued that
$SIG{__DIE__}
should be disabled inside ofeval
blocks, since it isn't people have grown to rely on it. Therefore in the interests of compatibility,try
does not disable$SIG{__DIE__}
for the scope of the error throwing code.
But feel free to disable it yourself
try {
local $SIG{__DIE__};
...
} catch { ... };
or rewrite try .. catch
to do what you want.
sub my_try (&;@) {
my ($try, @code_refs) = @_;
local $SIG{__DIE__};
Try::Tiny::try($try,@code_refs);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With