Subject: | $Error::THROWN takes precedence over $@ |
I have perl-5.8.8, the latest Error (0.17) running on Solaris 8 Sparc
and RedHat Enterprise Linux 3.0. I have this somewhat weird situation:
I override CORE::GLOBAL::die to make sure all exceptions (from
whatever Perl module they come from) are throwing some My::Error
exceptions, which are derived from the Error base class. Reason: this
way I can get the full stack trace of the exception. This however does
not work perfectly for some unknown reason - I failed to find that
out. Anyway, the resulting problem is this:
try {
... some code that has its own eval { die ... }, where the
die is redirected to My::Error->throw, such that $Error::THROWN
contains the exception object (1) ...
... more code ...
... code that uses Carp::croak, and that mysteriously does not
take the detour via My::Error->throw (2) ...
... more code, but not reached in this case...
} catch Error with {
... the usual print and exit ...
};
The problem is that the catch block will report the exception (1) and
not (2). This is because of this code in Error.pm:
$err = defined($Error::THROWN) ? $Error::THROWN : $@;
...which clearly prefers the content of Error::THROWN over $@.
I am wondering why that does not read:
if($ok) {
next CATCHLOOP if $more;
undef $err;
undef $Error::THROWN;
}
elsif($@) {
$err = ref($@) ? $@ :
$Error::ObjectifyCallback->({'text' =>$@});
}
elsif(defined $Error::THROWN) {
# this is always an object
$err = $Error::THROWN;
}
last CATCH;
This way an actual exception caught by the eval{} will always be
preferred, and the $Error::THROWN is just a fallback, or it may even
be obsolete. Or do I miss anything fundamental here?
Note that some Perl modules (AutoLoader, File::Temp) temporarily set
$SIG{__DIE__} which seems to cause some confusion. I think overriding
CORE::GLOBAL::die by a custom My::Error::dieReplacement(), which does
a My::Error->throw is OK, but it is not perfect, as some exceptions
(those by Carp::croak? I have seen the problem where (2) was
XML::LibXML, which croaks on an XML parse error) do not seem to be
redirectable this way. And abusing $SIG{__DIE__} for that purpose is
explicitely discoraged in the Perl docs.
Sorry, I cannot easily generate a test example - I hope you get the
idea, if not, do not hesitate to reply.
Cheers,
Marek