Re: Why does Net::SFTP trigger my die handler when no errors?



usenet@xxxxxxxxxxxxxxx wrote:
> xhoster@xxxxxxxxx wrote:
>
> > I think it would be nice, at least for debugging purposes, if you had
> > your sub print out the error message it was called with. Then you
> > would know what it was.
>
> Do you mean $! ? I wasn't sure $! would be reliable here. I actually
> included $! as I was trying to figure out what was going on, and I got
> a bunch of (seemingly) meaningless messages.

Mind you, I've never actually used SIG die handlers, so this is based on
the doc, not from experience, But I think what you should print would be
$_[0].

The routine indicated by $SIG{__DIE__} is called when a
fatal exception is about to be thrown. The error message is
passed as the first argument.



For example:
$ perl -le 'local $SIG{__DIE__}=sub {warn qq{Intercepted "$_[0]"}}; \
eval {die "foo"} '

results in:

Intercepted "foo at -e line 2.
" at -e line 1.

(OK, so now I guess I have actually used SIG die handlers, so disclaim my
disclaimer.)

>
> > However, from perldoc perlvar:
> > <snip perldoc>
> > So it would be my guess that Net::SFTP is dying from inside an eval, as
> > part of its normal course of business, and you are intercepting those
> > dies.
>
> I'm glad you were able to translate that perldoc statement (which I
> struggle to understand, with little success) into something that makes
> sense! Thanks!

You're welcome.

> >
> > But this lead me to ask a broader question. What are you trying to do,
> > and why are you using a SIG die handler, rather than eval{}, to do
> > whatever it is you are tyring to do?
> >
> The die handler is designed to catch my own die() calls. I die within
> my script under various dire circumstances, but I want to do some
> housecleaning before I really leave (dispatching final logging methods,
> closing databases cleanly, etc),

I think dispatching final logging methods should probably happen in an END
block, or perhaps should be automatically triggered when the logging object
goes out of scope and is destroyed (which happens even if you are exiting
via die).

For closing databases cleanly, it is not clear to me that one can generally
do a better job at handling that than the code already built into DBI does,
which is triggered when an open db handle goes out of scope or is
destroyed, for example during clean up after a uncaught "die". There are
exceptions to every generalization and YMMV, of course.


> so I use the handler. Maybe that's not
> the best way to do it...

I think that:

{
local $SIG{__DIE__} = sub { do_something_with_error($_[0]) };
## rest of code in block;
};

Should usually be functionally equivalent to:

eval {
## rest of code in block;
};
if ($@) { do_something_with_error($@); die $@ };

Except the latter doesn't intercept other peoples dies if those dies are in
evals of their own, while the former does. (One potential problem is that
the handler can be a closure upon lexicals in the block, while the if after
the eval can not.)


Xho

--
-------------------- http://NewsReader.Com/ --------------------
Usenet Newsgroup Service $9.95/Month 30GB
.