tags:

views:

201

answers:

2

Consider this simple class:

package Foo;
use Moose;
has foo => ( is => 'rw', isa => 'Int' );

And then this code:

use Try::Tiny;
use Foo;
my $f = try {
    Foo->new( foo => 'Not an Int' );
}
catch {
    warn $_;
};

The code dies with a nice big error message about type constraints failing.

I'd like to be able to extract what attribute failed (foo), what the reason was (failed type constraint) and what the value passed was (Not an Int) without having to parse an error string to get the info.

Something like this:

catch {
    if( $_->isa( 'MooseX::Exception::TypeConstraint' ) ) {
         my $attrib = $_->attribute;
         my $type   = $_->type;
         my $value  = $_->bad_value;

         warn "'$value' is an illegal value for '$attrib'.  It should be a $type\n"; 
    }
    else {
         warn $_;
    }
};

Is this possible? Is there a MooseX distribution that can make this happen? Better yet, is there some Moose feature that I missed that will make this possible?

Update: I am particularly interested in type constraints, but other Moose errors would be very good as well. I am also aware that I can throw objects with die. So, structuring exceptions in code I write is relatively easy.

+3  A: 

Check out MooseX::Throwable, which replaces the error_class value in the metaclass. The code looks a little old however (metaroles do support error class roles now), but the current method looks like it will still work.

Ether
This looked really promising, but the only attributes it has are: stack (the stack trace), previous_exception (in case we have nested exceptions), and message (the "Attribute (foo) does not ...."). Still stuck parsing the message.
daotoad
Aye, I suspect that someone is going to have to make a real exception class and explicitly construct it in cases of error (in the core code), rather than simply constructing a class around the raw messages that are created now. It would be quite a job to go through all the core code to change it to use these, but I'm sure lots of people will thank you!
Ether
@Ether, oops, I didn't mean to volunteer. :) I was really hoping to get a nice RTFM answer. C'est la vie.
daotoad
@daotoad. Come on. You could probably even get a grant from the Perl Foundation to do it! :)
molecules
+4  A: 

I haven't tried it myself, but I think MooseX::Error::Exception::Class might be what you're looking for.

cjm
This is very interesting. It works like MooseX::Throwable but is built on Exception::Class and defines the beginnings of an exception class hierarchy. Internally, it parses the error message to determine what sort of exception to throw.
daotoad