This question refers to this comment from Ikegami:
[...] But if you're going to put an eval around every statement, just use RaiseError => 0. [...]
in this thread.
What do I gain, if I set RaiseError
to 0
in such situations?
#!/usr/bin/env perl
use warnings;
use 5.10.1;
use DBI;
my $db = 'my_test_sqlite_db.sqlite';
open my $fh, '>', $db or die $!;
close $fh or die $!;
my ( $dbh, $sth );
eval {
$dbh = DBI->connect( "DBI:SQLite:dbname=$db", "", "", {} );
};
if ( $@ ) { print $@ };
my $table = 'my_sqlite_table';
say "RaiseError = 1";
say "PrintError = 0";
$dbh->{RaiseError} = 1;
$dbh->{PrintError} = 0;
eval {
$sth = $dbh->prepare( "SELECT * FROM $table" );
$sth->execute();
};
if ( $@ ) { print "ERROR: $@" };
say "\nRaiseError = 0";
say "PrintError = 1";
$dbh->{RaiseError} = 0;
$dbh->{PrintError} = 1;
eval {
$sth = $dbh->prepare( "SELECT * FROM $table" );
$sth->execute();
};
if ( $@ ) { print "ERROR: $@" };
say "\nRaiseError = 0";
say "PrintError = 0";
$dbh->{RaiseError} = 0;
$dbh->{PrintError} = 0;
eval {
$sth = $dbh->prepare( "SELECT * FROM $table" );
$sth->execute();
};
if ( $@ ) { print "ERROR: $@" };
Output:
RaiseError = 1
PrintError = 0
ERROR: DBD::SQLite::db prepare failed: no such table: my_sqlite_table at ./perl2.pl line 23.
RaiseError = 0
PrintError = 1
DBD::SQLite::db prepare failed: no such table: my_sqlite_table at ./perl2.pl line 33.
ERROR: Can't call method "execute" on an undefined value at ./perl2.pl line 34.
RaiseError = 0
PrintError = 0
ERROR: Can't call method "execute" on an undefined value at ./perl2.pl line 44.
If failed for some reasons, most $dbh methods will either:
RaiseError
option is set to 0) returnundef
RaiseError
option is set to 1) immediately exit the script ('die') with error reason given as exit message.The key point here is that it's up to you how to process the errors. If you wish, you can just ignore them, for example (the following obviously will work with
RaiseError
set to0
only):In this snippet (copied from @ikegami's answer you've mentioned in your question) you loop through some list of settings for DB connection; if some connection gives you an
undef
, you just go for another one, and do nothing with error.Usually, though, you have to do more than just 'nexting' when error happens - but then again, you have two choices: either check each
$dbh
-related statement with something like this:(as
or
parts will be executed only if their corresponding 'left parts' evaluate tofalse
in Boolean context)....or just wrap all this into Perlish 'try-catch' block:
What's to choose, it's up to you: it's a common decision between 'errors in return statements' (except that to fetch an actual error you have to ask $dbh object) and, well, exceptions.
But the bottom line is you cannot write just this:
... if you did set
RaiseError
to0
. In this case script won't die,$sth
will be assigned anundef
, and you get yourself a 'derivative' error (as you cannot call a method onundef
).And that exactly what happened in the last part of code in your original question.