使用 Try and Catch 消除错误

PyP*_*ngu 1 perl

这是我的第一个问题,所以如果我格式化/问错了,我提前道歉。

我正在使用 Perl 从文件中提取字符串,提交 Web 表单,并下载由网页创建的新文件。目的是让它循环运行 30,000 个文件,我估计这需要大约 8 天。我正在使用 WWW::Selenium 和 WWW::Mechanize 来执行网络自动化。我遇到的问题是,如果由于某种原因页面无法正确加载或互联网掉线一段时间,那么脚本会退出并给出一条错误消息,例如(取决于它失败的阶段):

Error requesting http://localhost:4444/selenium-server/driver/:
ERROR: Could not find element attribute: link=Download PDB File@href
Run Code Online (Sandbox Code Playgroud)

我希望脚本继续运行,进入下一轮循环,这样我就不必担心单轮循环是否会引发错误。我的研究表明使用Try::Tiny可能是最好的解决方案。目前我只使用下面的脚本try{...},它似乎可以抑制任何错误并允许脚本继续浏览文件。但是,我担心这似乎是一个非常生硬的解决方案,并且无法让我了解文件失败的原因/原因。

理想情况下,我希望将每次出现的文件名和错误消息打印到另一个文件中,然后在脚本完成后进行审查,但我很难理解如何使用catch{...}它,或者这是否是正确的解决方案。

Error requesting http://localhost:4444/selenium-server/driver/:
ERROR: Could not find element attribute: link=Download PDB File@href
Run Code Online (Sandbox Code Playgroud)

zdi*_*dim 5

您想查看、记录和查看所有错误(和警告)是完全正确的。Try::Tiny提供的机制和语法旨在简单易用。

use warnings;
use strict;
use feature qw(say);
use Try::Tiny;

my @fastas = <*.fasta>;

my $errlog = 'error_log.txt';
open my $fh_err, '>', $errlog  or die "Can't open $errlog for writing: $!";

foreach my $file (@fastas) {
    try {
        # processing, potentially throwing a die
    }
    catch {
        say $fh_err "Error with $file: $_";   # NOTE, it is $_ (not $! or $@)
    };
}
close $fh_err;

# Remove the log if empty
if (-z $errlog) { 
    say "No errors logged, removing $errlog";
    unlink $errlog or warn "Can't unlink $errlog: $!";
}    
Run Code Online (Sandbox Code Playgroud)

您可以保存处理失败的文件的名称,push @failed_files, $filecatch { }块。然后代码可以在主处理后再次尝试,如果您知道错误主要是由于随机连接问题。拥有失败文件的列表很方便。

请注意,在 v5.14 中,该模块解决的问题已得到修复,因此正常使用eval是可以的。在这一点上,这主要是一个偏好问题,但请注意,Try::Tiny它有自己的一些曲折。请参阅此帖子以进行讨论。

这解决了简单异常处理的问题,而不是代码的其余部分。