Perl如何捕获一次抛出的两个异常

1 perl eval exception bioperl

我正在解析一个大的EMBL文件(> 1G)并将其转换为gff文件.它有一些条目与传统的embl形成不匹配,因此导致bioperl模块抛出异常.我的问题是,因为有错误的条目只是整个序列的一小部分,我想继续编写脚本,暂时忽略该异常.但perl脚本始终由异常停止.

我在Linux操作系统下,使用perl版本5.8.8

我的perl脚本

use strict;
use Bio::SeqIO;
use Bio::Tools::GFF;
use warnings;
use Try::Tiny;

open (E ,">","emblError.txt");

if (@ARGV != 1) {    die "USAGE: embl2gff.pl   > outputfile.\n"; }

my $in = Bio::SeqIO->new(-file=>$ARGV[0],-format=>'EMBL');
eval {
   while (my $seq = $in->next_seq) {
      for my $feat ($seq->top_SeqFeatures) {
          my $gffio = Bio::Tools::GFF->new(-gff_version => 3);
          print $feat->gff_string($gffio)."\n";
        }
    }
};
if ($@) {
    warn "Oh no! [$@]\n";
}
Run Code Online (Sandbox Code Playgroud)

我得到的错误

Name "main::E" used only once: possible typo at embl2GFF3.pl line 7.

--------------------- WARNING ---------------------
MSG: exception while parsing location line [join(9174..9343,14214..14303)complement(9268..9363),complement(9140..9198),complement(8965..9034),complement(8751..8884),complement(8419..8535),complement(8232..8337),complement(7952..8149),complement(7256..7332),complement(7051..7175),complement(6769..6877),complement(6601..6659),complement(4690..6530))] in reading EMBL/GenBank/SwissProt, ignoring feature mRNA (seqid=XcouVSXmac70forkSpecies.Scaffold1050.final):
------------- EXCEPTION: Bio::Root::Exception -------------
MSG: Bad operator 1: had multiple locations 2, should be SplitLocationI
STACK: Error::throw
STACK: Bio::Root::Root::throw /usr/lib/perl5/site_perl/5.8.8/Bio/Root/Root.pm:472
STACK: Bio::Factory::FTLocationFactory::from_string /usr/lib/perl5/site_perl/5.8.8/Bio/Factory/FTLocationFactory.pm:210
STACK: Bio::Factory::FTLocationFactory::from_string /usr/lib/perl5/site_perl/5.8.8/Bio/Factory/FTLocationFactory.pm:204
STACK: Bio::SeqIO::FTHelper::_generic_seqfeature /usr/lib/perl5/site_perl/5.8.8/Bio/SeqIO/FTHelper.pm:133
STACK: Bio::SeqIO::embl::next_seq /usr/lib/perl5/site_perl/5.8.8/Bio/SeqIO/embl.pm:403
STACK: embl2GFF3.pl:14
-----------------------------------------------------------

---------------------------------------------------

--------------------- WARNING ---------------------
MSG: exception while parsing location line [join(14219..14303,14368..14513)complement(9140..9198),complement(8965..9034),complement(8751..8884),complement(8419..8535),complement(8232..8337),complement(7952..8149),complement(7256..7332),complement(7051..7175),complement(6769..6877),complement(6601..6659),complement(6461..6530))] in reading EMBL/GenBank/SwissProt, ignoring feature CDS (seqid=XcouVSXmac70forkSpecies.Scaffold1050.final):
------------- EXCEPTION: Bio::Root::Exception -------------
MSG: Bad operator 1: had multiple locations 2, should be SplitLocationI
STACK: Error::throw
STACK: Bio::Root::Root::throw /usr/lib/perl5/site_perl/5.8.8/Bio/Root/Root.pm:472
STACK: Bio::Factory::FTLocationFactory::from_string /usr/lib/perl5/site_perl/5.8.8/Bio/Factory/FTLocationFactory.pm:210
STACK: Bio::Factory::FTLocationFactory::from_string /usr/lib/perl5/site_perl/5.8.8/Bio/Factory/FTLocationFactory.pm:204
STACK: Bio::SeqIO::FTHelper::_generic_seqfeature /usr/lib/perl5/site_perl/5.8.8/Bio/SeqIO/FTHelper.pm:133
STACK: Bio::SeqIO::embl::next_seq /usr/lib/perl5/site_perl/5.8.8/Bio/SeqIO/embl.pm:403
STACK: embl2GFF3.pl:14
-----------------------------------------------------------

---------------------------------------------------
Oh no! [Can't call method "isa" on an undefined value at /usr/lib/perl5/site_perl/5.8.8/Bio/Seq.pm line 1142, <GEN0> line 538764.
]
Run Code Online (Sandbox Code Playgroud)

注意:我没有发布两次异常,它只是以这种方式发生,似乎只捕获了一个异常.

这是导致问题的embl文件块.mRNA条目导致第一个异常,CDS导致第二个异常.

FT   mRNA            join(9174..9343,14214..14303)
FT                   complement(9268..9363),complement(9140..9198),
FT                   complement(8965..9034),complement(8751..8884),
FT                   complement(8419..8535),complement(8232..8337),
FT                   complement(7952..8149),complement(7256..7332),
FT                   complement(7051..7175),complement(6769..6877),
FT                   complement(6601..6659),complement(4690..6530))
FT                   /gene="ENSXMAG00000014948"
FT                   /note="transcript_id=ENSXMAT00000015030"
FT   CDS             join(14219..14303,14368..14513)
FT                   complement(9140..9198),complement(8965..9034),
FT                   complement(8751..8884),complement(8419..8535),
FT                   complement(8232..8337),complement(7952..8149),
FT                   complement(7256..7332),complement(7051..7175),
FT                   complement(6769..6877),complement(6601..6659),
FT                   complement(6461..6530))
FT                   /gene="ENSXMAG00000014948"
FT                   /protein_id="ENSXMAP00000015010"
FT                   /note="transcript_id=ENSXMAT00000015030"
FT                   /db_xref="HGNC_transcript_name:ENO3-201"
Run Code Online (Sandbox Code Playgroud)

Axe*_*man 6

eval没有捕获低级Perl错误.还要检查$SIG{__DIE__}处理程序.如果一个骰子处理程序被写得不够熟练,它可能会死掉.例如,如果处理程序未检查$EXCEPTIONS_BEING_CAUGHT,则可能exit来自处理程序.

但只要查看你的输出,如果它打印出来:

Oh no! [Can't call method "isa" on an undefined value at 
/usr/lib/perl5/site_perl/5.8.8/Bio/Seq.pm line 1142, line 538764. ]
Run Code Online (Sandbox Code Playgroud)

然后,它没有做你说它正在做的事情.您eval 正在捕捉错误,或者您无法"Oh no!"在前面打印它.看起来它也在做自己的堆栈跟踪转储.

最后,看起来您的程序状态与数据有关,并且文件中的某些错误值可能会使其处于错误状态.无论出于何种原因,它无法创建一个BIO::Seq对象并将其传递给某个函数,该函数检查参数是否有问题isa.看起来输入文件中的违规行是#538,764.但我可能是错的.

注意:在评论中解决您的问题.如果Bioperl正在处理它发现的错误,并且你只是想要浏览一系列记录,那么我的建议是你把你的eval 内部循环 - 无论whilefor循环还是循环.对于某些多线程应用程序,这是一个非常标准的形式.

 while ( 1 ) {
     eval { $me->spin(); 1; } or say "WARNING: $@";
     # unless we are officially done, just get ready to
     # handle somebody causing an exception in our thread.
     last if $me->done; 
 }
Run Code Online (Sandbox Code Playgroud)

eval如果可能,请记住将其放在要恢复处理的位置.