Moose Loose Ends Part the Sixth



  • Its dig deep an play day here in the Moose-Pen

    I my last post I figured out how to set up Database:Accessor to get the 'MooseX::Constructor::AllErrors' object in the 'around BUILDARGS' and then play with it, without breaking my existing code.

    Today I want to see if I can change my error messages. I started by poking about in guts of ' MooseX::Constructor::AllErrors' and I discovered the the error messages are rather had coded;


    sub message {
        my $self = shift;
        return sprintf 'Attribute (%s) is required',
            $self->attribute->name;
    }
     

    Now that does not do me much good as I can't just do this in my 'around' sub

    eval{ $instance = $class->$orig($ops)};
    if ($@) {
    $@->errors[0]->message("I changed this");
    ...

    and expect it to work. I will have to work something else out.

    There is a 'misc' attribute on the 'AllErrors' I might be able to force that to my will. That attribute is and 'Array-ref' of 'MooseX::Constructor::AllErrors::Error::Mis' classes and that class has this attribute


    has message => (
        is => 'ro',
    isa => 'Str',
        required => 1,
    );
     

    All I need to do now is convert the other errors I am getting into 'Mis' errors and then return 'AllErrors' instance.

    What I came up with first is


    eval{ $instance = $class->$orig($ops)};
    if ($@) {
    foreach my $error ($@->missing()){
    my $misc = MooseX::Constructor::AllErrors::Error::Misc->new(
    message =>"Database::Accessor New Error: ".$error->message);
    $@->add_error($misc);
    }
    die $@;
    }
    else {
    return $instance;
    }

    In the 'around' and of course I added in a test;

    eval {
    $da = Database::Accessor->new({});
    };
    @errors = $@->errors;
    ok( index($errors[2]->message,'Database::Accessor New Error: Attribute (elements) is required') >=0 , "New error added" );

    and when I ran it I got;


    ok 10 - View: param alias fails
    ok 11 - Proper scalar error on empty build
    ok 12 - New error added

    That worked but now I have 3 errors when I should only have one. That I can deal with later.

    What I want is to get a little more useful message in there. Right now I am only getting 'Database::Accessor New Error: Attribute (elements) is require' with no line, package or file name which is nice to have.

    With the 'AllErrors' class I do have the access to calling info the 'caller' method which returns and array-ref of the calling info. I am going to add in line and file name to the new message like this


    foreach my $error ($@->missing()){
    my $misc = MooseX::Constructor::AllErrors::Error::Misc->new({message =>"Database::Accessor New Error: "
    . $error->message
    . " at Line "
    . $@->caller->[2]
    . " file: "
    . $@->caller->[1]});
    $@->add_error($misc);
    }

    and now I get;

    
    Database::Accessor New Error: Attribute (elements) is required at Line 157 file: D:\GitHub\database-accessor\lib/Database/Accessor.pm
    
    ok that is a little better but I am really not helping the end user much as I am only giving the location of where I called 'new' in the 'around' sub I can improve on that just a little more by first;
    
    around BUILDARGS => sub {
            my $orig  = shift;
            my $class = shift;
            my $ops   = shift(@_);
    ++      my ($package, $filename, $line, $subroutine) = caller(3);
    
    adding my own caller in at the very begiining of 'around'. Note here I am using the optional $i to the 'caller' function. Using (3) here forces perl to get the calling subroutine which gets me out of the Moose stack and back to the orignal calling program. I can now give this a try
    
     my $misc = MooseX::Constructor::AllErrors::Error::Misc->new({message =>"Database::Accessor New Error: "
                        . $error->message
                        . " at Line "
    --                  . $@->caller->[2]
    ++                  . $line
                        . " file: "
    --                  . $@->caller->[1]});                    
    ++                  . $filename});
                   $@->add_error($misc);
                }
    
    which gives me;
    
    Database::Accessor New Error: Attribute (elements) is required at Line 135 file: 30_view.t
    
    Perfect. Now to clean this all up, but that is a post for tomorrow. moose-calling-mark-little.jpg

    http://blogs.perl.org/users/byterock/2018/11/moose-loose-ends-part-the-sixth.html

 

© Lightnetics 2018