Reputation: 5072
I'm probably overlooking something simple, but I do not expect the below code to fail. It is behaving as if I wrote die
instead of fail
in the catch block.
The Failure does not get properly handled and the code dies.
sub foo()
{
try {
say 1 / 0;
CATCH { default { fail "FAIL" } }
}
return True;
}
with foo() {
say "done";
}
else
{
say "handled {.exception.message}"
}
Output:
FAIL
in block at d:\tmp\x.pl line 5
in any at d:\tmp\x.pl line 5
in sub foo at d:\tmp\x.pl line 4
in block <unit> at d:\tmp\x.pl line 11
Upvotes: 7
Views: 251
Reputation: 32404
To bring home to later readers the full force of what Yoda said in their comment, the simplest solution is to unlearn the notion that you have to try
in order to CATCH
. You don't:
sub foo()
{
say 1 / 0;
CATCH { default { fail "FAIL" } }
return True;
}
with foo() {
say "done";
}
else
{
say "handled {.exception.message}"
}
correctly displays:
handled FAIL
Upvotes: 6
Reputation: 2288
According to the Failure documentation this seems to be the defined behavior.
Sink (void) context causes a Failure to throw, i.e. turn into a normal exception. The use fatal pragma causes this to happen in all contexts within the pragma's scope. Inside try blocks, use fatal is automatically set, and you can disable it with no fatal.
You can try to use the no fatal
pragma.
sub foo() {
try {
no fatal;
say 1 / 0;
CATCH { default { fail "FAIL" } }
}
}
unless foo() {
say "handled"
}
Upvotes: 4