Custom Errors in Perl

package CustomErrors;

use strict;
use warnings;
use Carp qw(croak);

# A custom error type usually has the suffix "Error".
package ArgError;

sub new {
    my ($class, $arg, $message) = @_;
    return bless {
        arg     => $arg,
        message => $message,
    }, $class;
}

# Adding this error method makes ArgError implement
# the error interface in Perl.
sub error {
    my $self = shift;
    return "$self->{arg} - $self->{message}";
}

package main;

sub f {
    my $arg = shift;
    if ($arg == 42) {
        # Return our custom error.
        return (-1, ArgError->new($arg, "can't work with it"));
    }
    return ($arg + 3, undef);
}

# In Perl, we don't have a direct equivalent to errors.As,
# but we can check the type of an error using ref().
my ($result, $err) = f(42);
if (defined $err) {
    if (ref($err) eq 'ArgError') {
        print $err->{arg} . "\n";
        print $err->{message} . "\n";
    } else {
        print "err doesn't match ArgError\n";
    }
}

In this Perl translation:

  1. We define a custom ArgError package that serves as our error type. It has a constructor (new) and an error method that returns a string representation of the error.

  2. The f function is similar to the original, returning a tuple with a result and an error (or undef if there’s no error).

  3. In the main part of the script, we call f(42) and check if an error was returned.

  4. Instead of errors.As, we use Perl’s ref() function to check the type of the error. If it’s an ArgError, we print its properties.

To run this Perl script:

$ perl custom_errors.pl
42
can't work with it

This example demonstrates how to create and use custom error types in Perl, which can be useful for more detailed error handling in your programs.