I overrode CORE::GLOBAL::die
as described in brian d foy's article on the subject:
BEGIN {
*CORE::GLOBAL::die = sub {
say "In CORE::GLOBAL::die: [@_]";
CORE::die(@_) if $^S;
exit 1;
}
}
The ultimate goal is to write fatal errors to a log, but this is good enough for now. Let's create a database handle with RaiseError
turned on and do something to trigger an error:
use DBI;
# Wrong password
my $dbh = DBI->connect(..., { PrintError => 0, RaiseError => 1 });
Outputs:
In CORE::GLOBAL::die: [DBI connect(...) failed: Access denied for user ...
So far so good. Let's throw some bad SQL at it instead:
use DBI;
my $dbh = DBI->connect(..., { PrintError => 0, RaiseError => 1 });
my $sth = $dbh->prepare('SLECT 1');
$sth->execute;
Outputs:
DBD::mysql::st execute failed: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SLECT 1' at line 1 at ...
Hmmm, not what I expected (there's no In CORE::GLOBAL::die
message). According to the docs, when RaiseError
is on,
any method which results in an error will cause the DBI to effectively do a die("$class $method failed: $DBI::errstr")
I guess the key word is effectively, since I would expect an actual call to die
to invoke my version of CORE::GLOBAL::die
.
I can force all errors to die
by setting HandleError
:
my $dbh = DBI->connect(..., { HandleError => sub { die shift; } })
But since RaiseError
"can be used to force errors to raise exceptions rather than simply return error codes in the normal way," I don't understand why this is necessary. Why doesn't setting RaiseError
always result in a call to CORE::GLOBAL::die
on error? Isn't that the whole point of using it?