## 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