[plt-scheme] sqlite:finalize statement throws unexpectedly
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