[plt-scheme] sqlite:finalize statement throws unexpectedly

From: David Storrs (david.storrs at gmail.com)
Date: Mon Oct 12 17:19:50 EDT 2009

On Mon, Oct 12, 2009 at 5:07 PM, Jay McCarthy <jay.mccarthy at gmail.com> wrote:
> The contract for finalize specifies #2.

No, I got that.  I was just surprised.  It would be nice if the
contract was (-> statement? void?) instead of (-> open-statement?
void?).

> Re: #3 --- SQLite's sqlite3_finalize returns a status. I uniformly
> turn these status values into exns. My attitude is that the C API
> allows you to forget to handle errors but the Scheme API should never
> fail without warning.

Agreed, absolutely.  My thought was only that, in practice, the author
*must* have already dealt with this error, because an exception would
have been thrown when he tried to execute the statement in the first
place.  The finalize is re-raising an already-dealt-with error.  For
example:

;;    Assume the users table has a UNIQUE constraint on username
(let ((stmt (prepare db "insert into users (username, password) values
(?, ?)")))
  (with-handlers ((sqlite:exn? (finalize stmt) (void)))
    (run stmt 'Joe' 'pass1') ; executes fine, row is inserted
    (run stmt 'Joe' 'pass1') ; => exn:sqlite.  This user already exists
)

This is a simplified version of what I was just debugging.  It took me
a while to realize that the with-handlers was working fine; it's
simply that the handler function was re-raising the error, when I
expected it to ensure that the statement was finalized and then eat
the exception.

The way the sqlite module is currently written, one needs to wrap a
with-handlers around every call to finalize, just in case the
statement had problems when it was run.  That seems redundant.

--Dks


Posted on the users mailing list.