Chetan
Chetan

Reputation: 1281

Perl try catch for user defined exceptions

I want to know if perl has some try catch mechanism similar to python where i can raise user defined exceptions and handle accordingly.

PythonCode:

   try:
       number = 6
       i_num = 3
       if i_num < number:
           raise ValueTooSmallError
       elif i_num > number:
           raise ValueTooLargeError
       break
   except ValueTooSmallError:
       print("This value is too small, try again!")
       print()
   except ValueTooLargeError:
       print("This value is too large, try again!")
       print()

I know perl has try catch mechnism like below:

sub method_one {
    try {
        if ("number" eq "one") {
            die("one");
        } else {
            die("two");
        }
    } catch {
        if ($@ eq "one") {
            print "Failed at one";
        }
    }
}

OR

eval {
    open(FILE, $file) || 
      die MyFileException->new("Unable to open file - $file");
  };

  if ($@) {
    # now $@ contains the exception object of type MyFileException
    print $@->getErrorMessage();  
    # where getErrorMessage() is a method in MyFileException class
  }

I am concentrating more on the if checks on the catch. Is there a way i can avoid the checks for the different kind of errors i catch.

Upvotes: 5

Views: 1433

Answers (2)

Jacques
Jacques

Reputation: 1083

Like @daxim pointed out, there is TryCatch, but I am writing this for all those who would see this and to alert them that unfortunately TryCatch is now broken since the version 0.006020 of Devel::Declare on which TryCatch relies.

In replacement, there is Nice::Try which is quite unique and provides all the features like in other programming languages.

It supports exception variable assignment, exception class like the OP requested, clean-up with finally block, embedded try-catch blocks.

Full disclosure: I have developed Nice::Try when TryCatch got broken.

Upvotes: 1

daxim
daxim

Reputation: 39158

The closest solution is probably the straight-forward failures object and TryCatch for the type checking.

use failures qw(
    Example::Value_too_small
    Example::Value_too_large
);
use TryCatch;

try {
    my $number = 6;
    my $i_num = 3;
    if ($i_num < $number) {
        failure::Example::Value_too_small->throw({
            msg => '%d is too small, try again!',
            payload => $i_num,
        });
    } elsif ($i_num > $number) {
        failure::Example::Value_too_large->throw({
            msg => '%d is too large, try again!',
            payload => $i_num,
        });
    }
} catch (failure::Example::Value_too_small $e) {
    say sprintf $e->msg, $e->payload;
} catch (failure::Example::Value_too_large $e) {
    say sprintf $e->msg, $e->payload;
} finally {
    ...
}

You can upgrade from here to custom::failures, Throwable, Exception::Class.

Upvotes: 5

Related Questions