Home > Net >  How many exceptions does one CATCH block catch?
How many exceptions does one CATCH block catch?

Time:03-06

If multiple exceptions occur in a try{} block and there is only one CATCH{} block inside the try{} block, can this CATCH{} block catch any/all the exceptions? Or do I need one CATCH{} for each possible exception?

try { CATCH { default { say "seenError" }; }; die "1"; die "2"; die "3" }
seenError

In the example above, which "die" statement was caught? 1st? If I want to handle each exception, do I need to enclose each possible exception within one separate CATCH{} ?

CodePudding user response:

First of all: you do NOT need a try to have a CATCH block. In the Raku Programming Language, a CATCH block can live in any lexical scope.

So your example can become:

CATCH {
    default {          # $_ contains the exception
        say .message;  # show what the message was
    }
}
die "1";
die "2";
die "3";
say "still alive";

If you run it like this, it will just say "1", implying that only the first exception was caught. And that is correct, because you do NOT change anything about the situation: the exception is still active and will cause the termination of your program.

What you need, is to resume execution after the exception was handled. And there's a method for that: .resume. It doesn't work on all exceptions, but then you will be told it doesn't work.

Changing the program to:

CATCH {
    default {
        say .message;
        .resume;  # continue execution after where exception occurred
    }
}
die "1";
die "2";
die "3";
say "still alive";

This will show "1", "2", "3", "still alive".

So what does try do? Basically, it adds a CATCH block for you that will catch the first exception that it sees, put the exception in $! and return with Nil. You could think of a try block as a way to turn a fatal exception into a benign failure. You use it if you're not interested in why something failed. And try can also be a statement prefix. In short:

say try die;  # Nil

CodePudding user response:

(Please don't forget to accept Liz's answer. This is just an addendum to her answer.)

As Liz notes:

you do NOT need a try to have a CATCH block

And, as she implies, neither do you need a CATCH block when using try:

for 1, 2, 3 {
  try { print 'something ... '; .&die } or put "seenError: $!"
}

displays:

something ... seenError: 1
something ... seenError: 2
something ... seenError: 3

As Liz also outlines, if an exception is thrown and not .resumed during processing of code that's being tryd, or if there's an unhandled Failure, the try catches the exception/failure, puts the corresponding exception in $!, and returns Nil.

I mention this to introduce one final option that might be of interest: trys, which I created for my answer to the SOQ Returning values from exception handlers.

  • Related