Gregory Sysoev
Gregory Sysoev

Reputation: 311

How to create and to throw exceptions in Perl?

For example, php has exception like InvalidArgumentException with custom message 'Current group not found'.

And I can throw this exception in code.

if ($groupId === 0) {
    throw new InvalidArgumentException('Current group not found');
}

I can inherit this exception and create another child exception.

How exception works in Perl?

Upvotes: 7

Views: 3991

Answers (2)

James Edwards
James Edwards

Reputation: 1

I like using JT Smith's Ouch module, especially for web applications. This example is combining Ouch with TryTiny

use Ouch;
use Try::Tiny;
sub ProcessFiles {    die "Help, help, I'm being repressed";    }

sub DoLotsOfStuff {
    try {
        ProcessFiles();
    } catch {
        ouch 'That module/sub gave me an err', "died: $_";
    };
}
sub Driver {
    try {
        DoLotsOfStuff();
    } catch {
        if (hug($_)) {
            ouch 404, "Driver: $_"; # the caller wants a numeric code
        }
    }
}

try {
    Driver();
} catch {
    if (kiss(404,$_)) {
        ouch 404, "CallAPI: $_";
    }
}

Upvotes: 0

simbabque
simbabque

Reputation: 54323

There are various ways of doing that, but they're not built into Perl directly.

The simplest one is to die and eval {} to catch it.

eval {
  die "in a fire";
};
if ($@) {
  print "something went wrong";
}

If you want try, again there are various options. The most common one is Try::Tiny.

use Try::Tiny;

try {
  die;
} catch {
  print $_;
};

If you want to be cutting edge, there's research done by Paul Evans to get an actual keyword try into the Perl code. He's released a prototype of this as Syntax::Keyword::Try and has given various talks about it recently, including at Fosdem in 2021.

Now for the actual exceptions, there are, as is typical of Perl, several ways of doing that.

die can take objects as its argument rather than just strings, so you can pretty much emulate the behaviour of other languages.

Throwable is probably what I would go for today. You can easily create lots of these classes on the fly with Throwable::Factory.

use Throwable::Factory
  InvalidArgumentException => [qw( $id )];

sub foo {
  my $group_id = shift;
  unless ($group_id) {
    InvalidArgumentException->throw('Current group not found', id => $group_id);
  }
}

And later on to catch that, you can do:

use Try::Tiny;

try {
  foo(0);
} catch {
  warn $_;
};

Upvotes: 8

Related Questions