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已经被关闭了,它可能会出现。