Subject: | Inconsistent behaviour in rethrow |
Date: | Fri, 22 Sep 2006 13:58:19 +0200 |
To: | bug-Error [...] rt.cpan.org |
From: | Thomas Equeter <waba [...] waba.be> |
Error version: Error-0.17004
Perl version: v5.8.6
OS version: OpenBSD 3.9 / i386
(but confirmed on other versions/OSes, such as 5.8.8/Linux/amd64).
Most OO languages allow for "exception translation" - that is, catching
an exception, encapsulating the information in an other class and
re-throwing it. Error.pm supports that... but not always!
Generally speaking, using "plain" calls to die is equivalent to throwing
an Error::Simple. Yet, when doing this:
try { die "oops" } otherwise { die "oops2" };
we get:
at /usr/local/libdata/perl5/site_perl/Error.pm line 38.
instead of the expected:
oops2 at -e line 1.
that we get when doing
try { die "oops" } otherwise { throw Error::Simple "oops2" };
Oops. Exception translation works, but only when rethrowing objects.
That's inconsistent...
Some research shows that if the error is correctly detected by Error.pm,
it's mysteriously lost when it comes to rethrowing it. After some more
work, it appears that the following snippet does not do what one might
think:
eval { local $@; die "oops" }; print "no error\n" unless $@;
This was probably unforeseen at the time of writing of version 0.17003,
which introduced this bug with the intend of making the exception
available in $@ in catch/otherwise clauses. Of course the alteration of
this variable was to be as local as possible and resulted in a local
declaration in the eval block.
But since actually we still want to have the modified version of $@
past the eval, the fix is simply to move the local declaration out of
this scope. It will not affect the program logic, as the success of the
eval is determined using its return value ($ok), not $@.
Attached is a patch for the catch and otherwise code, with a testcase
that illustrates the problem.
Best regards,
-Thomas Equeter.
Message body is not shown because sender requested not to inline it.