我使用Data::FormValidator来处理DBIx :: Class中的一些数据验证(通过DBIx::Class::Validation)。 DBIC ::如果验证失败,验证最终会croak $results
,其中$results
是Data::FormValidator::Results对象。不幸的是,这个croak不会触发我在DBIC调用中的try / catch。
挖掘一下,我做了这个简化的测试用例(完全不包括DBIC):
use strict;
use Data::FormValidator;
use TryCatch; #or Try::Tiny or eval, same results for each
#setup a profile and values that fail under that profile
my $input_profile = {
required => [ qw( good_ip bad_ip ) ],
constraints => {
good_ip => 'ip_address',
bad_ip => 'ip_address',
}
};
my $validator = new Data::FormValidator({default => $input_profile});
my $input_hashref = {
'good_ip' => '127.0.0.1',
'bad_ip' => '300.23.1.1',
};
try {
my $results = $validator->check($input_hashref,'default');
die $results;
} catch (Data::FormValidator::Results $e) {
print STDERR "failed with ".scalar(@{$e->invalid('bad_ip')})." invalid\n";
}
我希望我的catch块会被触发。相反,没有任何事情发生(继续执行)。
查看Results对象的来源,我发现它使用bool
方法重载了success
。删除它可以解决我的问题,但我不明白为什么。如果这是整个问题,有没有一种解决它的好方法?
答案 0 :(得分:4)
这是TryCatch中的一个错误。 $results
字符串化为空字符串,TryCatch调用if $@
时应调用if defined $@
。
这是一个没有Data :: FormValidator的例子:
use strict;
use warnings 'all';
use 5.010;
package Foo;
use overload '""' => sub { '' };
sub new {
bless {}, $_[0];
}
package main;
use TryCatch;
try {
my $foo = Foo->new;
die $foo;
}
catch($e) {
say "<<<$e>>>";
}
当Perl词法分析器遇到某些关键字时,TryCatch使用Devel::Declare注入自定义代码。在这种情况下,它会生成如下内容: *
try;
{
local $@;
eval {
my $foo = Foo->new;
die $foo;
};
$TryCatch::Error = $@;
}
if ($TryCatch::Error) {
由于$@
是空字符串,if ($TryCatch::Error)
为false,永远不会输入catch
块。
这是一个错误(TryCatch的many之一)。请改用eval
或Try :: Tiny(只记得检查defined
,而不是真实/虚假)。
*如果您想确切了解注入的内容,请将环境变量TRYCATCH_DEBUG
设置为1。