Perl 如何从Moose获取结构化异常?

Perl 如何从Moose获取结构化异常?,perl,moose,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),原因是什么(失

考虑这个简单的类:

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
),原因是什么(失败的类型约束),传递的值是什么(
不是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 $_;
    }
};
这可能吗?是否有一种性别分布可以让这种情况发生?更好的是,是否有一些驼鹿的特点,我错过了,将使这成为可能


更新:我对类型约束特别感兴趣,但其他Moose错误也会很好。我也知道我可以用
骰子投掷对象
。因此,在我编写的代码中构造异常相对容易。

签出,它取代了元类中的
error\u类
值。但是,代码看起来有点旧(元角色现在确实支持错误类角色),但是当前的方法看起来仍然有效。

我自己没有尝试过,但我想这可能是您想要的。

大约一年前,我在#moose IRC频道上问过同样的问题。答案是Moose并不真正支持结构化异常。。。。然而

人们普遍认为,这是驼鹿的一个缺点,应该加以纠正,但在任何地方引入例外的任务都是乏味的,而且还没有执行(afaik)

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

由于无法从麋中得到可靠的结构化异常,所以考虑在设置新值时,使用自省逐个测试每个类型约束。有时这是一种可行的方法


顺便说一句:注意有。

这看起来很有希望,但它唯一的属性是:堆栈(堆栈跟踪)、上一个异常(如果我们有嵌套的异常)和消息(属性(foo)不…)。仍然无法解析消息。是的,我怀疑有人将不得不创建一个真正的异常类,并在出现错误时显式地构造它(在核心代码中),而不是简单地围绕现在创建的原始消息构造一个类。这将是一个相当大的工作,通过所有的核心代码,以改变它使用这些,但我相信很多人会感谢你!哎呀,我不是有意自愿的。:)我真的希望得到一个好的RTFM答案。“这就是生活。”道蟾蜍。来吧你甚至可以从Perl基金会得到一笔拨款来做这件事!)这很有趣。它的工作原理类似于MooseX::Throwable,但它是基于Exception::Class构建的,并定义了异常类层次结构的开始。在内部,它解析错误消息以确定抛出何种类型的异常。不幸的是,它已经有一段时间没有更新了,并且几乎所有地方的测试都失败了。哎哟!那是一只赫库瓦虫子。虽然Exception::Class看起来很有趣,但我认为在一个项目中使用两个不同的对象构建库是错误的。Throwable很有趣,但我认为异常是继承有意义的地方之一。你扔掉的任何东西都应该是例外,而不是“可以扔掉”(不管这意味着什么…)。我不是100%相信继承是正确的解决方案。也许答案是一个具有适当属性的单一异常类。我还不确定。这个bug已经被关闭了,它可能会出现。