IndexedDB: Finalizing error handling

Hi All,

We've over the last few months had a number of threads about details
of error handling. However the spec has remained in a pretty bad state
with both inconsistencies and ambiguities. I went over the threads and
filled in some gaps and edited into the drafts something that I hope
will work for everyone. If you have concerns, or if you see any
mistakes I've done in the spec. Please speak up.

Here's the behavior the spec now defines:

- Have .error on both IDBRequest and IDBTransaction.
- When a single request fails, set .error to a DOMError which
represents the failure and fire an "error" event on the IDBRequest.
IDBTransaction.error remains null at this time.
- If someone calls .preventDefault() on the "error" event which is
fired for the failed request, do nothing more.
- If the event is not cancelled though a call to .preventDefault() we
set IDBTransaction.error to the same value as was set on the
IDBRequest (note that we don't use the exact same DOMError instance.
Just a new one with the same .name). Then abort the transaction (see below).
- When a transaction is aborted set IDBTransaction.error
appropriately. Then if there are still outstanding requests, set
.error to a new DOMError with .name "AbortError" and fire a "error"
event on each such request. Finally fire a "abort" event on the
transaction object. Note that this is a change. The spec used to say
that IDBTransaction.error was set after firing "error" on all
outstanding requests, but it seems useful to be able to find out why
the transaction was aborted from withing the request error handler.
- If there is an error not tied to a specific request, for example a
quota error or IO error while committing, we set IDBTransaction.error
to a DOMError representing the error and follow the normal abort
steps.
- If there's an error while a transaction is committed the transaction
is aborted per the descriptions above. This will mean that no "error"
events are fired since there are no remaining requests. Only an
"abort" event is fired.
- When a transaction is aborted through a call to abort(), leave
IDBTransaction.error as null but otherwise follow the normal abort
steps. This means that we'll still fire a "abort" event as normal, and
we'll still set .error to a "AbortError" on any still outstanding
requests and fire an "error" event on them.
- If an exception is thrown from a "success" or "error" event set
IDBTransaction.error to an "AbortError" and follow the normal abort
steps.

There was also a weird note in the steps for committing a transaction
which said "Even if the event is cancelled (by a call to
preventDefault), follow the steps for aborting a transaction". I'm not
sure which event this intended to reference though since the "commit"
event fires after the transaction is committed and so we obviously
can't abort the transaction. I replaced the text with a note that
explained that once the "commit" event starts firing, the transaction
can't be aborted under any circumstances.

I also noticed that the spec didn't say to throw an error if you pass
an invalid argument as the direction argument to
openCursor/openKeyCursor. However we did say to throw TypeError if you
pass an invalid mode argument to the transaction() function. I fixed
this by making openCursor/openKeyCursor also throw TypeError for
invalid values for direction.

/ Jonas

Received on Friday, 2 March 2012 03:00:52 UTC