Holli
Holli

Reputation: 5072

Failure failing in CATCH

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

Answers (2)

raiph
raiph

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

LuVa
LuVa

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

Related Questions