Ben Dauphinee
Ben Dauphinee

Reputation: 4191

Why am I seeing DBI errors on the console even though I have wrapped the DBI calls in an eval?

I have a database query that I am running inside an eval, to trap the error. Problem is that the error message is outputting to console, even though it is being trapped. How do I stop the error message from doing this, as I want to parse it myself and spit back my own messages?

my $dbh = DBI->connect('dbi:Pg:dbname=database;host=localhost',
    'user', 'pass', 
    {RaiseError => 1}
);

eval{
    $sth = $dbh->prepare($sql);
    $sth->execute;
};

if($@){
    #Do my parse/print stuff here I know
}

Upvotes: 3

Views: 3674

Answers (3)

runrig
runrig

Reputation: 6524

You can specify 'PrintError => 0' in your connect call (or use HandleError):

my $dbh = DBI->connect('dbi:Pg:dbname=database;host=localhost', $user, $passwd, {
  PrintError => 0,
  RaiseError => 1,
});

Or to set per statement handle:

my $sth = $dbh->prepare("SELECT * from my_table");
$sth->{PrintError} = 0;
$sth->execute();
...etc.

Also, don't depend on $@ for indicating an error. A better way to use eval is:

my $result = eval {
  ...
  $sth->...etc.
  1;
}
unless ($result) {
  # Do error handling..log/print $@
}

Upvotes: 6

Ether
Ether

Reputation: 54014

It's not a good idea to trap and ignore errors, whether they are fatal or not. Also, it is not advisable to check $@ in the way you are doing it (see the questions on this site about perl exceptions for better ways to trap exceptions; I use Try::Tiny below, which is arguably the lightest-weight route of all).

Instead of proceeding with a DBI operation when an earlier one might have failed, you should check error conditions at every step:

use strict; use warnings;
use Try::Tiny;

try {
    my $sth = $dbh->prepare($sql) or die $dbh->errstr;
    $sth->execute or die $sth->errstr;
} catch {
    print "got error $_\n";
    # return from function, or do something else to handle error
};

And remember, always use strict; use warnings; in every module and script. Your code excerpt suggests that you are not yet doing this.

Upvotes: 14

mob
mob

Reputation: 118695

eval { } will trap a fatal error (from a die or Carp::croak call), but not a non-fatal error message (from warn or carp). To handle warning messages, see how to install a warning handler in documentation for %SIG or warn.

A trivial workaround is to use a trivial warning handler inside your eval block.

eval {
    local $SIG{__WARN__} = sub { };
    ...
};

See also: perlfaq7: How do I temporarily block warnings?

Upvotes: 2

Related Questions