如何从Moose获得结构化异常?

时间:2010-02-11 00:19:02

标签: perl moose

考虑这个简单的类:

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

然后这段代码:

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

代码消失了一个关于类型约束失败的很好的大错误消息。

我希望能够提取哪些属性失败(foo),原因是什么(失败类型约束)以及传递的值是什么(Not an Int)而无需解析获取信息的错误字符串。

这样的事情:

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 $_;
    }
};

这可能吗?是否有可以实现这一目标的MooseX发行版?更好的是,是否有一些我错过的Moose功能可以实现这一目标?

更新:我对类型限制特别感兴趣,但其他Moose错误也非常好。我也知道我可以使用die抛出对象。因此,在我编写的代码中构造异常相对容易。

3 个答案:

答案 0 :(得分:4)

我自己没有尝试过,但我认为MooseX::Error::Exception::Class可能就是你想要的。

答案 1 :(得分:3)

签出MooseX::Throwable,它取代了元类中的error_class值。但代码看起来有点旧(metaroles现在支持错误类角色),但是当前的方法看起来仍然有用。

答案 2 :(得分:1)

一年前我有同样的问题,并在#moose IRC频道询问。答案是,Moose并不真正支持结构化异常......但是。

人们普遍认为应该修复Moose的缺点,但是在各地引入例外的任务是繁琐的,并且还没有(afaik)进行过。

MooseX :: Error :: Exception :: Class中的方法非常脆弱,因为它基于解析来自Moose的消息。

由于您无法从Moose真正获得可靠的结构化异常,因此在设置新值时,请考虑使用内省逐个测试每个类型约束。有时这是一种可行的方法。

顺便说一句:请注意a nasty bug in the way Moose handles composite constraints