dgaramond2 has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying out the Error module. The doc says:

catch CLASS with BLOCK: This clause will cause all errors that satisfy "$err->isa(CLASS)" to be caught and handled by evaluating "BLOCK". "BLOCK" will be passed two arguments. The first will be the error being thrown. The second is a reference to a scalar variable. If this variable is set by the catch block then, on return from the catch block, try will continue processing as if the catch block was never found.
Now, is it possible to continue to the point right after the exception was originally thrown, while still have the exception handled first?

use Error qw(:try);

sub foo {
  throw Error::Simple \-text => "oops";
  print "1\n";
}

try {
  foo();
}
catch Error::Simple with {
  my ($err, $cont) = @_;
  print "2\n";
  $$cont = 1;
};

I want both print statements to print. If I don't surround the throw(), only "2" is printed. If I do, only "1" is printed.

Imagine the old DOS' "abort, retry, continue" scenario.

Replies are listed 'Best First'.
Re: Can we continue after an exception?
by GrandFather (Saint) on May 31, 2007 at 04:24 UTC

    In a word: No. throw/catch is a way of dealing with unrecoverable (in the local context) errors. If it is a recoverable error in the local context don't throw - handle the error (perhaps by calling an error handling routine) and carry on.


    DWIM is Perl's answer to Gödel
Re: Can we continue after an exception?
by perrin (Chancellor) on May 31, 2007 at 04:42 UTC
    In addition to what GrandFather said, I recommend you avoid the try/catch syntax in this module and look at Exception-Class-TryCatch instead. The block approach that Error uses can cause a lot of subtle bugs.
      Hm, unfortunately that module is not sexy enough for my taste :-) Thanks for the warning though. Any recommendations on other Exception modules for use in Perl5? I cannot seem to get a sense of major consensus or even widespread usage at all in this area.
        I played around with the various exception modules, and eventually settled on what Perl already provides:
        eval { step1(); step2(); }; if (my $error = $@) { # rethrow error if we can't handle it die $error unless ref $error && $error->isa('My:Error'); handle_error($error); }

        clint

        The only one that is widely used is Exception::Class. Seriously, you are taking your life in your hands if you use Error's try/catch syntax. It caused multiple hard-to-find bugs in a large system I worked on.
Re: Can we continue after an exception?
by educated_foo (Vicar) on May 31, 2007 at 06:38 UTC
    Yes. The key is to "handle" the exception before you throw it and the stack is hopelessly unwound. Something like this:
    { our @handlers; sub my_die { for (@handlers) { return if $_->(@_); } die(@_); }; sub try { my $fn = shift; local @handlers = (@_, @handlers); $fn->(); } sub blah { my_die 'omg!'; } sub unblah { try sub { blah() }, sub { if ($_[0] =~ /!/) { print "ok\n"; 1 } }; } unblah() }