[Bioperl-l] how to catch exception error

Steve Chervitz sac@bioperl.org
Wed, 4 Sep 2002 01:08:07 -0700 (PDT)


For the record, here's the fancy way to handle exceptions. This might feel more
comfortable to you if you're coming from a Java/C++ background:

use Error qw(:try);

try {
      $seq = $gb->get_Seq_by_acc($acc);
}
catch Bio::Root::Exception with {
    my $error = shift;
    print "Can't retrieve $acc due to Bioperl exception:\n$error\n";
}
otherwise {
    my $error = shift;
    print "Can't retrieve $acc due to non-Bioperl exception:\n$error\n";
};

Notes/observations:

* You need to have Error.pm installed (not included with Bioperl but easily
obtained from CPAN).

* This seems like a lot of extra trouble without much added value. Why not use 
 the simpler eval{} block?

In this case, I'd agree that using the try-catch construct doesn't buy you
much, except maybe improved readability. 

Where it would really help is if there were certain types of exceptions from
which you could recover. Then you could write a specific catch block for those
types. For example (and this is pure fiction at this point in time), if the
above method call can throw a Bio::DB::RetrievalTypeUnsupported exception,
*and* you were aware of this fact by way of good documentation ;), you could
write a catch block such as:

catch Bio::DB::RetrievalTypeUnsupported with {
    my $error = shift;
    # re-attempt the call using a different retrieval type
}

Throwing typed exceptions is a fairly recent addition to Bioperl, so most
modules don't exploit it. To learn more about this and other exception stuff,
check out examples/exceptions (or scripts/exceptions on the main trunk).

Module writers: One advantage to throwing typed exceptions instead of untyped
exceptions (i.e., using named parameters, -class, -text, -value, in your
$self->throw() calls instead of just a simple string) is that the class of
exception is displayed prominently in the exception output. 

For example, if you throw an exception like this:

  $self->throw(-class => 'Bio::Root::FileOpenException',
               -text  => "Can't open file $file: $!" );

the output will look like this:

------------- EXCEPTION: Bio::Root::FileOpenException -------------
...
-------------------------------------------------------------------

This way the basic nature of the error is obvious. This happens regardless of
whether or not Error.pm is installed. The Bio::Root::Exception module defines
several general classes of exceptions you might find useful. These are
automatically available to all Bio::Root::Root subclasses.

Defining new exception types is really easy. For a demo of this, see
examples/exceptions/TestObject.pm (or scripts/exceptions/TestObject.pm on the
trunk). If you're module does throw typed exceptions, be sure to document this
fact in the method POD sections (in a "Throws:" line).

Apologies for the long-winded explanation. Now back to the regularly scheduled
program.

Steve

PS. Yes, I realize this thread is over two-months old. I consider any email
that's significantly younger than my son (now 20 mos) to be fair game. :)

--- Heikki Lehvaslaiho <heikki@ebi.ac.uk> wrote:
> Damien,
> 
> Write:
> 
> 
> eval {
>      $seq = $gb->get_Seq_by_acc($acc);
> };
> print "$@ Could not retrieve $acc\n" if $@;
> 
> Yours,
> 	-Heikki
> 
> 
> Damien Mattei wrote:
> > 
> > when doing something like this:
> > 
> > use Bio::DB::GenBank;
> > 
> > $gb = new Bio::DB::GenBank();
> > 
> > # this returns a Seq object :
> > $seq = $gb->get_Seq_by_acc("AC019220");
> > 
> > i get an exception that stop my program:
> > ------------- EXCEPTION  -------------
> > MSG: WebDBSeqI Request Error
> > 
> > STACK Bio::DB::WebDBSeqI::_request 
> > /usr/lib/perl5/site_perl/5.6.1/Bio/DB/WebDBSeqI.pm:523
> > STACK Bio::DB::WebDBSeqI::get_seq_stream 
> > /usr/lib/perl5/site_perl/5.6.1/Bio/DB/WebDBSeqI.pm:375
> > STACK Bio::DB::NCBIHelper::get_Stream_by_acc 
> > /usr/lib/perl5/site_perl/5.6.1/Bio/DB/NCBIHelper.pm:466
> > STACK Bio::DB::WebDBSeqI::get_Seq_by_acc 
> > /usr/lib/perl5/site_perl/5.6.1/Bio/DB/WebDBSeqI.pm:161
> > STACK main::nxtbac ./gmap.pl:338
> > STACK toplevel ./gmap.pl:25
> > 
> > --------------------------------------
> > 
> > 
> > is there a way in bioperl to catch exception
> > as it is possible in Java or C++ ?
> > 
> > 
> > Damien Mattei
> > C.N.R.S / U.N.S.A - UMR 6549
> > mailto:mattei@unice.fr
> > http://www-iag.unice.fr/
> > 
> > _______________________________________________
> > Bioperl-l mailing list
> > Bioperl-l@bioperl.org
> > http://bioperl.org/mailman/listinfo/bioperl-l
> 
> 
> -- 
> ______ _/      _/_____________________________________________________
>        _/      _/                      http://www.ebi.ac.uk/mutations/
>       _/  _/  _/  Heikki Lehvaslaiho          heikki@ebi.ac.uk
>      _/_/_/_/_/  EMBL Outstation, European Bioinformatics Institute
>     _/  _/  _/  Wellcome Trust Genome Campus, Hinxton
>    _/  _/  _/  Cambs. CB10 1SD, United Kingdom
>       _/      Phone: +44 (0)1223 494 644   FAX: +44 (0)1223 494 468
> ___ _/_/_/_/_/________________________________________________________
> 
> _______________________________________________
> Bioperl-l mailing list
> Bioperl-l@bioperl.org
> http://bioperl.org/mailman/listinfo/bioperl-l


=====
Steve Chervitz
sac@bioperl.org

__________________________________________________
Do You Yahoo!?
Yahoo! Finance - Get real-time stock quotes
http://finance.yahoo.com