Skip to content

In "object store storage operation", be more explicit about how to handle ConstraintError from an index #477

@dumbmatter

Description

@dumbmatter

In the object store storage operation, steps 5-3 and 5-4 both cover situations where an index can result in a ConstraintError as the result of the operation:

5-3. If index’s multiEntry flag is false, or if index key is not an array key, and if index already contains a record with key equal to index key, and index’s unique flag is true, then this operation failed with a "ConstraintError" DOMException. Abort this algorithm without taking any further steps.

5-4. If index’s multiEntry flag is true and index key is an array key, and if index already contains a record with key equal to any of the subkeys of index key, and index’s unique flag is true, then this operation failed with a "ConstraintError" DOMException. Abort this algorithm without taking any further steps.

They both end with "Abort this algorithm without taking any further steps." But in the case where you call event.preventDefault() in the request's error handler to prevent the transaction from aborting, that's not enough. You also need to undo any changes made in earlier steps, specifically increasing the key generator's current number (step 1) and storing the record in the object store (step 4). This behavior is reflected in WPT (request-event-ordering tests) and current browsers.

I'm not sure if that is somehow implicit in the phrase "Abort this algorithm without taking any further steps." But if you look elsewhere in the spec like for aborting a transaction it is much more explicit about reverting changes:

All the changes made to the database by the transaction are reverted. For upgrade transactions this includes changes to the set of object stores and indexes, as well as the change to the version. Any object stores and indexes which were created during the transaction are now considered deleted for the purposes of other algorithms.

Maybe similar language should be there for object store storage, like:

All the changes made to the database by this operation are reverted. This includes changes to the records stored in the object store and the key generator's current number.

Or @nolanlawson suggested maybe that language from "abort a transaction" could be refactored into its own algorithm/definition and used in both places.

(I'm posting this because I wrote fake-indexeddb mostly by trying to implement all the algorithms in the spec, and I just now realized that I missed handling this situation.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions