Re: capture exception

[email protected]
Newsgroups gmane.comp.apache.mod-perl
Message-ID <20170530140314.GA15786@pali>
Hi!

Please note that true value in $@ is *not* necessary condition for
checking if error in eval occurred. And similarly empty string or logic
false value in $@ is *not* necessary condition that eval succeeded.

The only thing which is guaranteed is undef return value from eval in
case it failed. So correct check is:

my $success = eval {
  # MY CODE
  1;
};

unless ($success) {
  # HANDLE ERROR, $@ may (but does not have to) contain error
}

"1;" in eval block is there to set $success to 1. In case MY CODE throw
error, $success is set to undef by perl.

Note that $@ is propagated back, so you should localize $@ before
calling eval. This is especially required if MY CODE (or function called
from MY CODE) calls also eval.

So you can use this pattern:

{
  local $@;
  eval {
    # MY CODE
    1;
  } or do {
    # HANDLE ERROR in $@ (but may be undef!)
  };
}

If you do not write 1; then return value is taken from the last call in
MY CODE. So if problem is also when last function return non zero, then
you can remove "1;". You can also combine it with "and" block, but
beware for and/or logical blocks:

{
  local $@;
  eval {
    func_which_may_die_or_fail_with_zero();
  } and do {
    print "function succeeded\n";
    func_may_fail_with_zero();
  } or do {
    my $err = $@ || 'unknown error';
    warn "Error: $err\n";
    rollback();
  };
}

But I suggest to use module like Try::Tiny or Try::Catch which handle
above eval and $@ logic for you and you can easily write:

try {
  # MY CODE
} catch {
  # HANDLE ERROR in $_ (may be undef!)
  my $err = $_ || 'unknown error';
};

On Tuesday 30 May 2017 09:39:53 John Dunlap wrote:
> Yes, I do that extensively and it works perfectly. It's as close to a true
> Try/Catch block as we have in the perl world. However, I *usually* do not
> return values from it because I use this construct to control my database
> transaction demarcation and using the return value from outside of the eval
> wouldn't be inside the transaction. With that said, I have had to do it
> from time to time and it works just fine. Also, it is advisable to copy the
> contents of $@ into a separate variable immediately. My understanding is
> that this can prevent some weird concurrency issues, under some conditions.
> My general form looks something like this,
> 
> my $return = eval {
>     # BEGIN DATABASE TRANSACTION
> 
>     # DO SOME STUFF
> 
>     # COMMIT DATA BASE TRANSACTION
> 
>     return 'SOME VALUE';
> };
> 
> if ($@) {
>     my $error = $@;
> 
>     # ROLLBACK DATABASE TRANSACTION
> 
>     # LOG ERROR
> }
> 
> 
> On Tue, May 30, 2017 at 4:47 AM, James Smith <[email protected]> wrote:
> 
> > Not really a mod_perl question but you can always wrap your method call in
> > an eval
> >
> > my $ret = eval { $m->...() };
> >
> > And then check $@ for the error message
> >
> >
> > On 2017-05-26 02:08 AM, Peng Yonghua wrote:
> >
> >> greeting,
> >>
> >> I am not so good at perl/modperl,:)
> >>
> >> In the handler, a method from a class was called, when something dies
> >> from within the method, what's the correct way the handler will take?
> >>
> >> for example, I wrote this API which works right if given a correct domain
> >> name:
> >>
> >> http://fenghe.org/domain/?d=yahoo.com
> >>
> >> server response:
> >> var data={"registration":"domain may be taken","domain":"yahoo.com"}
> >>
> >> If given a wrong domain name:
> >>
> >> http://fenghe.org/domain/?d=yahoo.nonexist
> >>
> >> The server returns 500.
> >>
> >> This is because, in the handler, I used this module (wrote also by me):
> >>
> >> http://search.cpan.org/~pyh/Net-Domain-Registration-Check-0.
> >> 03/lib/Net/Domain/Registration/Check.pm
> >>
> >> And in the module, croak like this was happened,
> >>
> >> croak "domain TLD not exists" unless tld_exists($tld);
> >>
> >> When handler meets the croak, it dies (I guess) and server returns 500.
> >>
> >> How will I make the full system work right? fix on handler, or the module
> >> itself?
> >>
> >> Thanks.
> >>
> >
> >
> >
> > --
> > The Wellcome Trust Sanger Institute is operated by Genome Research
> > Limited, a charity registered in England with number 1021457 and a company
> > registered in England with number 2742969, whose registered office is 215
> > Euston Road, London, NW1 2BE.
> 
> 
> 
> 
> -- 
> John Dunlap
> *CTO | Lariat *
> 
> *Direct:*
> *[email protected] <[email protected]>*
> 
> *Customer Service:*
> 877.268.6667
> [email protected]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.