Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get a better error message if a required attribute is not supplied in Moose?

Tags:

perl

moose

I'm brand new to Moose. Up until today our environments have been on Perl 5.8.2 which would not support Moose.

I'm working through some examples, and I thought that the "required => 1" setting on an attribute would be handy, however when I try using that option, the error message that is returned is not really usable.

Here's an example:

cat.pl:

#!/usr/bin/perl

{
    package Cat;
    use Moose;
    use Modern::Perl;

    has 'name' => (
        is => 'ro',
        required => 1,
    );
    sub meow {
        my $self = shift;
        say 'Meow!';
    }
}

use Modern::Perl;

my $alarm = Cat->new();
$alarm->meow();
$alarm->meow();
$alarm->meow();

When I run it:

Attribute (name) is required at /app/perl5/perl-5.10.1/lib/site_perl/5.10.1/aix-thread-multi-64all/Class/MOP/Class.pm line 581
        Class::MOP::Class::_construct_instance('Moose::Meta::Class=HASH(0x110ac1a00)', 'HASH(0x110c3b3c0)') called at /app/perl5/perl-5.10.1/lib/site_perl/5.10.1/aix-thread-multi-64all/Class/MOP/Class.pm line 554
        Class::MOP::Class::new_object('Moose::Meta::Class=HASH(0x110ac1a00)', 'HASH(0x110c3b3c0)') called at /app/perl5/perl-5.10.1/lib/site_perl/5.10.1/aix-thread-multi-64all/Moose/Meta/Class.pm line 258
        Moose::Meta::Class::new_object('Moose::Meta::Class=HASH(0x110ac1a00)', 'HASH(0x110c3b3c0)') called at /app/perl5/perl-5.10.1/lib/site_perl/5.10.1/aix-thread-multi-64all/Moose/Object.pm line 28
        Moose::Object::new('Cat') called at cat.pl line 20

If one of our non-perl operators see an error message like that, they will probably freak out. I'm afraid they will not realize that all 5 lines in the error message are actually a part of the same error.

Is there a way to get a nice error message if a required attribute is not supplied?

Something like croak, I can imagine a message like this:

Attribute (name) is required at cat.pl line 20

Again, I'm new to Moose so this may be an easy setting that I am missing.

Thanks in advance!

like image 985
BrianH Avatar asked Apr 19 '11 18:04

BrianH


2 Answers

I think I may have found a solution to my requirement, but I'm not sure if it is the best solution.

And, as @Tanktalus points out, there is value to having a detailed error message.

For the purposes of my question, the MooseX::Constructor::AllErrors extension seems to work:

#!/usr/bin/perl

{
    package Cat;
    use Moose;
    use MooseX::Constructor::AllErrors;
    use Modern::Perl;

    has 'name' => (
        is => 'ro',
        required => 1,
    );
    sub meow {
        my $self = shift;
        say 'Meow!';
    } 
}

use Modern::Perl;

my $alarm = Cat->new(); 
$alarm->meow(); 
$alarm->meow(); 
$alarm->meow();

On running, I get:

Attribute (name) is required at cat.pl line 21

Which is what I was thinking.

Since I am not familiar at all with Moose, is this extension okay to use, or will it "muffle" all of the error messages?

like image 135
BrianH Avatar answered Oct 12 '22 02:10

BrianH


I prefer the long error message - because if I'm missing a required parameter, I want my non-perl users to freak out: I obviously missed something in development, unit-test, and system test if it gets all the way to a user with this type of message.

Mind you, I also leave fatal warnings turned on when I go to production. I prefer my failures to be spectacular so that I can't accidentally ignore them.

like image 34
Tanktalus Avatar answered Oct 12 '22 02:10

Tanktalus