JohnnyLoo JohnnyLoo - 1 year ago 141
Perl Question

PERL - Disable DBI HandleError in certain sections

Is there a way to "turn off" the DBI HandleError attribute in Perl in some sections of a script just like RaiseError can be turned off?

Example:

my $dbh = DBI->connect("DBI:SQLite:dbname=file.db","","",{ PrintError => 0, RaiseError => 0,
HandleError => sub{ Log("ERROR: Something failed in db"); exit 1 } })
or die "Couldn't connect";

for my $table (@db_tables){
$dbh->do("delete from $table")
or do{ Log("ERROR: Delete failed"); next };

Log("Table [$table] content was deleted");
}

exit 0;


Here I don't want the HandleError to kill the script just because the content of one of those tables could not be deleted. I want to manually handle the error.

Answer Source

The HandleError attribute can be changed at all times. Since you access it directly by going into the hash reference inside your $dbh, you can simply localize it.

for my $table (@db_tables){
    local $dbh->{HandleError}; # it's now undef
    $dbh->do("delete from $table") 
          or do{ Log("ERROR: Delete failed"); next };

    Log("Table [$table] content was deleted");
}

A better implementation would be to handle the error properly, and to only set the localization once. For that, create an outer scope around your loop.

{
    local $dbh->{HandleError} = sub {
        my (undef, $error) = @_
        Log("ERROR: Delete failed ($error)");
    };

    for my $table (@db_tables){
        $dbh->do("delete from $table") 
            and Log("Table [$table] content was deleted");
    }
}

In both cases, the value will only be overridden while code in this scope and any scopes inside it is run. Once the scope is over, it will automatically be restored.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download