Re: DBI error and $@
by Arguile (Hermit) on Dec 06, 2001 at 21:32 UTC
|
Personally when I'm doing transaction handling I use Error or other exception handling modules. The addition of a little syntatic sugar make a lot of difference. You can also define your own error classes for more complex failovers.
use Error qw(:try);
# ... code passes ...
try {
# Execute a few queries
$sth->execute( $str );
# If we're here everything is fine, let's commit.
$dbh->commit;
}
catch Error with {
my $err = shift;
print "Transaction Failed: $err";
$dbh->rollback;
};
| [reply] [d/l] |
Re: DBI error and $@
by frankus (Priest) on Dec 06, 2001 at 20:41 UTC
|
| [reply] [d/l] |
|
No, perhaps I wasn't clear -- sorry. I said I can print the value of $DBI::errstr, but it was my understanding that "If there is a syntax error or runtime error, or a die statement is executed, an undefined value is returned by eval, and $@ is set to the error message."
And from the examples I mention above, I thought that is what they are trying to catch for. They're not looking at $DBI::errstr, they're looking at $@. I want to know why and such.
--
notsoevil
--
Jeremiah 49:32 - And their camels shall be a booty. . .
| [reply] |
Re: DBI error and $@
by broquaint (Abbot) on Dec 06, 2001 at 21:16 UTC
|
I'm not entirely sure why the eval() is breaking, but $@ is not the variable you are looking for. That's because $@ contains what goes wrong inside an eval(), whereas DBI->errstr() will tell you what went wrong with the database.
HTH
broquaint
Update: I believe that $@ is dependent on the DBI driver you're using, so it's probably best not to rely on it as a means of communicating what went wrong. | [reply] |
|
| [reply] |
|
I believe you have misunderstood the advice: you combine the approaches, you don't replace one with the other.
You have to set $@ yourself by calling die in the normal way:
eval {
$db->do($sql) or die $db->errstr();
$db->commit();
}
if ($@) {
warn "DB error: $@\n";
}
| [reply] [d/l] [select] |
|
|
In addition to what the anonymous monk has to say (I'll admit it, it was me, not logged in), take a look at the code that creates the DB handle in that example, where RaiseError is set to 1 (i.e. true). That means the die is automatically called on a DB error, so it's functionally equivalent to the code "AM" provided.
HTH
I mistrust all systematizers and avoid them. The will to a system shows a lack of integrity -- F. Nietzsche
| [reply] [d/l] |
|
Re: DBI error and $@
by runrig (Abbot) on Dec 06, 2001 at 23:00 UTC
|
This doesn't make sense, you say $@ is not being printed, but it must be set to something or else you wouldn't even
be executing that warn statement.
Are you getting a warning from
somewhere else in the script (and are all of your warnings
as descriptive as this one? :)
Update: When I'm in doubt about variables that must be there, but don't appear
to be, then I resort to something like: my $hex = unpack("H*", $@);
warn "Warning: [$@] [$hex]";
You've got the latest versions of DBI & DBD??
| [reply] [d/l] |
|
There is no other code. :)
There are no other warnings. :)
I know it should print something. However it is not, hence my confusion.
I'd really just like an explanation of the examples in the Perl DBI book and/or Randal's article on why they used the format:
eval {
$dbh->do($statement);
$dbh->commit();
}
if ($@) {
$dbh->rollback();
die $@;
}
I believe my sample code is an example of this (save the $dbh->rollback, but that isn't the issue). The examples check $@ and then die with it, after a rollback. If $@ isn't being printed (interpolated into my warn string), how does the conditional execute? If it is executing (and hence doing a rollback) when $@ does not have a printable value, this may affect my transactions.
Or am I just completely batty?
--
notsoevil
--
Jeremiah 49:32 - And their camels shall be a booty. . .
| [reply] [d/l] |
|
Hmmm ... using mysql v3.23.36, Perl 5.6.0, and DBI v1.20:
# connect with RaiseError set to true
eval {
$dbh->do('UPDATE a SET x = y');
$dbh->commit();
};
if ($@) {
warn "flurg!: $@";
warn "flurg!: ", $dbh->errstr();
}
yielded:
DBD::mysql::db do failed: Table 'mysql.a' doesn't exist at ./test_db_e
+val.pl line 20.
flurg!: DBD::mysql::db do failed: Table 'mysql.a' doesn't exist at ./t
+est_db_eval.pl line 20.
flurg!: Table 'mysql.a' doesn't exist at ./test_db_eval.pl line 25.
jeffa
L-LL-L--L-LL-L--L-LL-L--
-R--R-RR-R--R-RR-R--R-RR
F--F--F--F--F--F--F--F--
(the triplet paradiddle)
| [reply] [d/l] [select] |
|
Re: DBI error and $@
by notsoevil (Pilgrim) on Dec 06, 2001 at 23:46 UTC
|
Either I am a complete idiot (highly possible) or there is something quirky going on (less possible).
I run the code again, and I get the print out of $@ as expected. In the same log, only a few lines above, I can see where it wasn't printing out.
I could have swore that I didn't make any changes since I was getting the error, but perhaps I just did.
I am going to keep an eye on the code and its output and keep running tests with it. Thanks to everyone for trying to help.
--
a complete idiot
--
Jeremiah 49:32 - And their camels shall be a booty. . .
| [reply] |