Re: massaging error messages
- From: Tim.Bunce@xxxxxxxxx (Tim Bunce)
- Date: Sun, 25 Feb 2007 22:29:39 +0000
On Sun, Feb 25, 2007 at 03:36:07PM +0000, Tim Bunce wrote:
On Sat, Feb 24, 2007 at 09:20:35PM +0000, Will Parsons wrote:
I'm trying to change the text of error messages, for example the following:
DBD::SQLite::db do failed: table X already exists(1) at dbdimp.c line 269
From the user's point of view, "table X already exists" is valuableinformation, but "at dbdimp.c line 269" is useless.
I've attempted to do this using the HandleError attribute with a function:
sub handle_error {
$_[0] =~ s/ at dbdimp.c line \d+//;
print STDERR "db error: $_[0]\n"; # for debug
return 0;
}
The print statement shows the handler is changing the error text, but
the contents of $DBI:errstr on return from an offending statement show
the original text.
How can I do this?
Umm. I'd expect it to work. $_[0] is the same SV that's passed to
warn/croak for PrintError/RaiseError.
If you send me a patch that moves the HandleError tests from t/10examp.t
into a separate file and adds a new test for this problem, then I'll
try to fix it :)
Having said that, I don't see any value in the _sqlite_error() function
in DBD::SQLite adding the file and line number into the error message.
In fact the code needs changing anyway to use the newer way to record
errors. That'll mean you could use the DBI's SetErrHandler hook.
I'll do that and post a patch including the above change.
Here's the patch.
Matt, I hope you approve.
Funnily enough, adding the tests found a bug in the way the DBI set_err
function handles HandleSetErr (fixed in the next release).
Tim.
diff -ru DBD-SQLite-1.13/dbdimp.c DBD-SQLite-1.13.tim1/dbdimp.c
--- DBD-SQLite-1.13/dbdimp.c 2006-09-08 05:50:50.000000000 +0100
+++ DBD-SQLite-1.13.tim1/dbdimp.c 2007-02-25 22:02:19.000000000 +0000
@@ -36,11 +36,7 @@
_sqlite_error(char *file, int line, SV *h, imp_xxh_t *imp_xxh, int rc, char *what)
{
dTHR;
-
- SV *errstr = DBIc_ERRSTR(imp_xxh);
- sv_setiv(DBIc_ERR(imp_xxh), (IV)rc);
- sv_setpv(errstr, what);
- sv_catpvf(errstr, "(%d) at %s line %d", rc, file, line);
+ DBIh_SET_ERR_CHAR(h, imp_xxh, NULL, rc, what, NULL, NULL);
if (DBIS->debug >= 3) {
PerlIO_printf(DBILOGFP, "sqlite error %d recorded: %s at %s line %d\n",
@@ -441,7 +437,7 @@
{
int pos;
if (!SvIOK(param)) {
- int len;
+ STRLEN len;
char *paramstring;
paramstring = SvPV(param, len);
if( paramstring[len] == 0 && strlen(paramstring) == len) {
diff -ru DBD-SQLite-1.13/t/06error.t DBD-SQLite-1.13.tim1/t/06error.t
--- DBD-SQLite-1.13/t/06error.t 2002-09-08 13:18:46.000000000 +0100
+++ DBD-SQLite-1.13.tim1/t/06error.t 2007-02-25 22:26:03.000000000 +0000
@@ -1,20 +1,37 @@
use Test;
-BEGIN { plan tests => 2 }
+BEGIN { plan tests => 8 }
use DBI;
+my @set_err;
+
unlink('foo');
-my $db = DBI->connect('dbi:SQLite:foo', '', '', { RaiseError => 1, PrintError => 0 });
+my $db = DBI->connect('dbi:SQLite:foo', '', '', {
+ RaiseError => 1,
+ PrintError => 0,
+ HandleSetErr => sub { push @set_err,$_[2]; return 0; },
+});
+
eval {
$db->do('ssdfsdf sdf sd sdfsdfdsf sdfsdf');
};
-ok($@);
+my $err = $@;
+ok($err);
+ok($err, qr/syntax error/);
+ok($DBI::err);
+ok($DBI::errstr);
$db->do('create table testerror (a, b)');
$db->do('insert into testerror values (1, 2)');
$db->do('insert into testerror values (3, 4)');
$db->do('create unique index testerror_idx on testerror (a)');
+@set_err = ();
eval {
$db->do('insert into testerror values (1, 5)');
};
-ok($@);
+$err = $@;
+ok($err);
+ok($err, qr/column a is not unique/);
+ok(scalar @set_err, 1);
+ok("@set_err", qr/column a is not unique/);
+@set_err = ();
.
- References:
- massaging error messages
- From: Will Parsons
- Re: massaging error messages
- From: Tim Bunce
- massaging error messages
- Prev by Date: Re: massaging error messages
- Next by Date: DBD::Oracle-1.19 installation error
- Previous by thread: Re: massaging error messages
- Next by thread: DBD::Oracle-1.19 installation error
- Index(es):
Relevant Pages
|
|