【问题标题】:Disable DBI HandleError in certain sections在某些部分禁用 DBI HandleError
【发布时间】:2018-05-13 07:14:23
【问题描述】:

有没有办法在脚本的某些部分“关闭”Perl 中的 DBI HandleError 属性,就像可以关闭 RaiseError 一样?

例子:

my $dbh = DBI->connect("DBI:SQLite:dbname=file.db","","",{ PrintError => 0, RaiseError => 0, 
                                                           HandleError => sub{ Log("ERROR: Something failed in db"); exit 1 } }) 
        or die "Couldn't connect";
        
for my $table (@db_tables){
  $dbh->do("delete from $table") 
          or do{ Log("ERROR: Delete failed"); next };

  Log("Table [$table] content was deleted");
}
    
exit 0;

在这里,我不希望 HandleError 仅仅因为无法删除其中一个表的内容而终止脚本。我想手动处理错误。

【问题讨论】:

  • 查看 Try::Tiny 并考虑将该部分放入“try”块中,然后如果需要,您可以在其上添加自己的错误处理。

标签: perl dbi


【解决方案1】:

HandleError attribute 可以随时更改。由于您通过进入 $dbh 中的哈希引用直接访问它,因此您可以简单地 localize 它。

for my $table (@db_tables){
    local $dbh->{HandleError}; # it's now undef
    $dbh->do("delete from $table") 
          or do{ Log("ERROR: Delete failed"); next };

    Log("Table [$table] content was deleted");
}

更好的实现是正确处理错误,并且只设置一次本地化。为此,请在循环周围创建一个外部范围。

{
    local $dbh->{HandleError} = sub {
        my (undef, $error) = @_
        Log("ERROR: Delete failed ($error)");
    };

    for my $table (@db_tables){
        $dbh->do("delete from $table") 
            and Log("Table [$table] content was deleted");
    }
}

在这两种情况下,只有在此范围内的代码及其内部的任何范围内运行时,该值才会被覆盖。一旦范围结束,它会自动恢复。

【讨论】:

  • 优秀。谢谢你。我应该考虑将其本地化为 RaiseError 属性。
猜你喜欢
  • 1970-01-01
  • 2020-09-14
  • 2019-06-17
  • 1970-01-01
  • 2011-01-29
  • 1970-01-01
  • 1970-01-01
  • 2021-08-09
  • 1970-01-01
相关资源
最近更新 更多