Just a little More Moose

Its never stop improving day here in the Moose-Pen

As I was cleaning things up today I found yet another little improvement I can do to my error messages. Right now when I have deeply buried bad item such as the 'names' in this $in_hash

$in_hash = {
    view => { name => 'People' },
    elements => [ { name => 'first_name', }, { name => 'last_name', }, ],
    gather    => {
                elements => [
                    {
                        name => 'first_name',
                        view => 'People4'
                    },
                ],
                conditions => [
                    {
                        left => {
                            name => 'last_name',
                            view => 'People7'
                        },
                        right => { names => 'test' },
                    },
                ]
            }
way down in the bottom in the in the final 'right' attribute, I will get this error message;

Database::Accessor new Error:
The following Attribute is required: (name)
With constructor hash:
all good but there could be a number of places here that 'name' could be out of place. I am going to try and fix that; First a little re-factoring in Database::Accessor::Roles::AllErrors I take out the code like this

                      ( $invalid->attribute->documentation )
                        ? $invalid->attribute->documentation . "->"
                        : "",
                        $invalid->attribute->name,
from both of the ' sprintf's that are in '_one_error' sub and move them into a function;

Now why do this?

When I was poking about in the code I discovered a little more data that is available to me from the error attributes that will come in handy. It is called the 'definition_context' and will give me the calling class. Now for the new function;

sub _get_hint {
    my ($attribute) = @_;
    my $hint = "";
    if ($attribute->documentation){
       $hint = $attribute->documentation ;
    }
    elsif ($attribute->definition_context->{package}){
        $hint =  $attribute->definition_context->{package};
        $hint =~ s/Database\:\:Accessor\:\://;
    }
    return $hint
           ."->"
           .$attribute->name();
}
The only funky thing is the ' definition_context' is just a hash-ref rather that a class of some form but I can live with that. Back in the '_one_error' I now stub that function in like this;

                push(
                    @errors,
                    _get_hint($missing->attribute)
                );
and
              push(
                    @errors,
                    sprintf(
                        "'%s' Constraint: %s",
                        _get_hint($invalid->attribute),
                        $invalid->attribute->type_constraint->get_message(
                            $invalid->data
                        )
                    )
                );
and now I get this on my error message

Database::Accessor new Error:
The following Attribute is required: (Element->name)
With constructor hash:
…
a little better. Now if I only could find some way to get the invalid data down into my function so I can point to in in that hash display?? MattHelm_Moose-1240x805.jpg

Leave a comment

About byterock

user-pic Long time Perl guy, a few CPAN mods allot of work on DBD::Oracle and a few YAPC presentations