in reply to Rethrowing with die $@ considered harmful
I won't go into too much detail, but (among other things) it had a "login" and "logout" method. Each updated a global session data hash with info about the current user. These methods throw exceptions if something goes wrong. Nothing fancy so far.
Later, I wanted to make a facility for administrators to "become" a normal user (think Unix "su"). However, I wanted to make it so that if the operation failed, it would restore the existing session. So, I wrote this code:
Now this looks fine, but any errors were being mysteriously swallowed. Turns out the culprit was my LDAP object destructor, which did this:my %ubackup = %udat; eval { $self->logout; $self->login(username => $username); }; if($@) { %udat = %ubackup; die $@; }
ie shut down the connection, and ignore errors.sub DESTROY { my ($self) = @_; eval { $self->_unbind; }; }
The login/logout methods create LDAP objects as part of their operation, so of course they were being destroyed at the end of the method. The call to _unbind was trampling $@.
This was a nightmare to track down. The solution was to simply localise $@ in the destructor.
local $@; eval { $self->_unbind; };