Subject: bug#58363: [PATCH 3/3] Improve error data signaled by sqlite-execute et al.

From: Jonas Bernoulli <[email-masked]>
Date: Sat, 22 Oct 2022 13:07:15 +0200

Eli Zaretskii <[email-masked]> writes:

>> From: Jonas Bernoulli <[email-masked]>
>> Date: Fri, 21 Oct 2022 23:06:36 +0200
>> 
>> +  Lisp_Object ext_errcode = make_fixnum (sqlite3_extended_errcode (sdb));
>> +  const char *errmsg = sqlite3_errmsg (sdb);
>> +  return list4 (errstr, errmsg ? build_string (errmsg) : Qnil,
>> +		errcode, ext_errcode);                      ^^^^
>
> Is that Qnil really a good idea here?  What will an error message look
> like in that case?  We may wish replacing Qnil with some standard
> text, if it looks better.

Based on some data I collected from SQLite documentation and code, this
is only relevant in some rare cases:

   ((1  SQLITE_ERROR      "SQL logic error")
    (2  SQLITE_INTERNAL   nil)
    (3  SQLITE_PERM       "access permission denied")
    (4  SQLITE_ABORT      "query aborted")
    (5  SQLITE_BUSY       "database is locked")
    (6  SQLITE_LOCKED     "database table is locked")
    (7  SQLITE_NOMEM      "out of memory")
    (8  SQLITE_READONLY   "attempt to write a readonly database")
    (9  SQLITE_INTERRUPT  "interrupted")
    (10 SQLITE_IOERR      "disk I/O error")
    (11 SQLITE_CORRUPT    "database disk image is malformed")
    (12 SQLITE_NOTFOUND   "unknown operation")
    (13 SQLITE_FULL       "database or disk is full")
    (14 SQLITE_CANTOPEN   "unable to open database file")
    (15 SQLITE_PROTOCOL   "locking protocol")
    (16 SQLITE_EMPTY      nil)
    (17 SQLITE_SCHEMA     "database schema has changed")
    (18 SQLITE_TOOBIG     "string or blob too big")
    (19 SQLITE_CONSTRAINT "constraint failed")
    (20 SQLITE_MISMATCH   "datatype mismatch")
    (21 SQLITE_MISUSE     "bad parameter or other API misuse")
    (22 SQLITE_NOLFS      "large file support is disabled")
    (23 SQLITE_AUTH       "authorization denied")
    (24 SQLITE_FORMAT     nil)
    (25 SQLITE_RANGE      "column index out of range")
    (26 SQLITE_NOTADB     "file is not a database")
    (27 SQLITE_NOTICE     "notification message")
    (28 SQLITE_WARNING    "warning message"))

We would get nil for SQLITE_INTERNAL ("internal malfunction ...
application should never see this"), SQLITE_EMPTY ("not currently
used"), and SQLITE_FORMAT ("not currently used").  The comments in
parentheses are from https://www.sqlite.org/rescode.html.  We will
"never" see these error codes, and if we do see 2/SQLITE_INTERNAL,
it is IMO okay if the shown error is a bit ugly.