## names of modules/subs changed for convenience... package MySOAP; use strict; use My::DBIWrapper; sub foo { my $dbh; eval { $dbh = My::DBIWrapper->connect; ...bunch of processing... }; if( my $err = $@ ) { eval{ $dbh->disconnect }; ## just make sure die $err; ## reraise so SOAP->fault returns true } } #### ## I really didn't want to subclass DBI, so I just ## encapsulate a database handle and proxy all ## subroutine calls that My::DBIWrapper doesn't ## understand via AUTOLOAD. Other subs have been omitted for bravity package My::DBIWrapper; use strict; our( $AUTOLOAD ); sub connect { my $class = shift; my $self = { dbhandle => undef }; bless $self, $class; $self->dbhandle( DBI->connect( .... ) ); return $self; } sub AUTOLOAD { ( my $subname = $AUTOLOAD ) =~ s/^.*:://; if( eval{ $_[0]->dbhandle && $_[0]->dbhandle->can( $subname ) ) { eval "sub $subname { shift->dbhandle->$subname(\@_) }"; die $@ if $@; goto &$AUTOLOAD; } Carp::croak( "Undefined subroutine $AUTOLOAD called" ); } sub DESTROY { my $self = shift; my $dbh = $self->dbhandle; if( $dbh ) { eval{ $dbh->disconnect }; } } 1; #### 1: package Foo; 2: sub DESTROY 3: { 4: $@ = ''; 5: ## local $@ = ''; <-- this will work 6: } 7: 8: package main; 9: eval { 10: my $foo = bless {}, 'Foo'; 11: die; 12: }; 13: if( $@ ) { 14: die $@; 15: } #### ## with local $@ me@myhost> perl ~/test.pl; echo $? Died at /home/me/test.pl line 14 255 ## without local $@ me@myhost> perl ~/test.pl; echo $? 0