From jamesd at jml.net Fri Oct 17 07:54:29 2003 From: jamesd at jml.net (James Davis) Date: Thu Aug 5 00:08:38 2004 Subject: OxPM: Handling errors from DBI Message-ID: I'm not exactly an expert in Perl and have found difficulty in getting a concise answer to my questions from Google. I've written a perl script that uses DBI to insert data into a MySQL table. However, the script will evoke all sorts of nastyness should MySQL be unavailble, or become unavailable during the execution of the script. I don't want to loose my data! :-) What's the best way to catch these errors so that I can recover sanely and spool the data for insertion into the table at a later time when MySQL is available again? Ta, James From kake at earth.li Fri Oct 17 12:46:44 2003 From: kake at earth.li (Kate L Pugh) Date: Thu Aug 5 00:08:38 2004 Subject: OxPM: Handling errors from DBI In-Reply-To: References: Message-ID: <20031017174644.GB8518@the.earth.li> On Fri 17 Oct 2003, James Davis wrote: > I've written a perl script that uses DBI to insert data into a MySQL > table. However, the script will evoke all sorts of nastyness should > MySQL be unavailble, or become unavailable during the execution of > the script. I don't want to loose my data! :-) If you expect the unavailability to be transient, you could look into Mark's 'Attempt' module: http://search.cpan.org/~markf/Attempt/ It will try to do things over again if they fail the first time. Kake From andrewc-oxpm at piffle.org Sat Oct 18 13:00:17 2003 From: andrewc-oxpm at piffle.org (Andrew Chadwick) Date: Thu Aug 5 00:08:38 2004 Subject: OxPM: Handling errors from DBI In-Reply-To: References: Message-ID: <20031018180017.GA28842@piffle.org> (I'm re-sending this unsigned and using my subscription address. If it's a duplicate of something you already received, please ignore it) On Fri, Oct 17, 2003 at 01:54:29PM +0100, James Davis wrote: > I'm not exactly an expert in Perl and have found difficulty in getting a > concise answer to my questions from Google. I've written a perl script > that uses DBI to insert data into a MySQL table. However, the script will > evoke all sorts of nastyness should MySQL be unavailble, or become > unavailable during the execution of the script. I don't want to loose my > data! :-) > > What's the best way to catch these errors so that I can recover sanely and > spool the data for insertion into the table at a later time when MySQL is > available again? It's all there in the manpage, at least on my system :) DBD::mysql can be instructed to throw any errors it encounters through the normal Perl mechanism. These can be caught and reported via an eval/if($@) incantation, which is a bit like try/catch in other languages. If you're prepared to queue the data you want to insert in the current Perl process, then something like the following should do the trick. You may want to split the connect/tidyup parts into other fragments of code if it's to be a long-running process: there's no special magic to doing everything in just a single eval {}. #!/usr/bin/perl -w use strict; use DBI; my $ok = 0; for my $try (1 .. 10) { my $dbh; eval { $dbh = DBI->connect ("DBD:mysql:host=foobox.domain;database=bardb", "thuduser", "bangpass", {RaiseError => 1}) or die "Oops: couldn't connect to MySQL"; my $sth = $dbh->prepare(" INSERT INTO MyTable SET id = ?, field_a = ? field_b = ? ") or die "Whoops: failed to make query"; $sth->execute(@ARGV) or die "Failed silently!"; $sth->finish; }; my $err = $@; $dbh->disconnect if defined $dbh; undef $dbh; if ($err) { warn $err; $ok = 0; } else { $ok = 1; last; } my $t = $try * 5; warn "$0: insert failed: sleeping for $t seconds\n"; sleep $t; } if (! $ok) { # Gracefully recover from a no-win situation: perhaps # write @ARGV to a file. } -- Andrew Chadwick