Re: [w3c/IndexedDB] Mark transactions inactive during key serialization (PR #479)

nolanlawson left a comment (w3c/IndexedDB#479)

Thanks for the feedback @asutherland! I just checked, and it appears that none of Firefox/Chromium/WebKit actually throw a `TransactionInactiveError` in the case of `continue`/`continuePrimaryKey` (see test draft below).

<details><summary>Click to see test draft</summary>

```js
promise_test(async testCase => {
  const db = await createDatabase(testCase, database => {
    database.createObjectStore('store');
  });

  const transaction = db.transaction(['store'], 'readwrite');
  const objectStore = transaction.objectStore('store');

  objectStore.put({}, 0);
  objectStore.put({}, 1);
  const cursor = await new Promise((resolve, reject) => {
    const cursorReq = objectStore.openCursor();
    cursorReq.onerror = reject;
    cursorReq.onsuccess = e => resolve(e.target.result);
  });

  let getterCalled = false;
  const activeKey = ['value that should not be used'];
  Object.defineProperty(activeKey, '0', {
    enumerable: true,
    get: testCase.step_func(() => {
      getterCalled = true;
      assert_throws_dom('TransactionInactiveError', () => {
        objectStore.get('key');
      }, 'transaction should not be active during key serialization');
      return 'value that should not be used';
    }),
  });
  cursor.continue(activeKey);
  await promiseForTransaction(testCase, transaction);
  db.close();

  assert_true(getterCalled,
    "activeKey's getter should be called during test");
}, 'Transaction inactive during key serialization in IDBCursor.continue()');

promise_test(async testCase => {
  const db = await createDatabase(testCase, database => {
    const objectStore = database.createObjectStore('store');
    objectStore.createIndex('idx', 'name');
  });

  const transaction = db.transaction(['store'], 'readwrite');
  const objectStore = transaction.objectStore('store');

  objectStore.put({ name: 'a' }, 0);
  objectStore.put({ name: 'b' }, 1);
  const idx = objectStore.index('idx')
  const cursor = await new Promise((resolve, reject) => {
    const cursorReq = idx.openCursor();
    cursorReq.onerror = reject;
    cursorReq.onsuccess = e => resolve(e.target.result);
  });

  let getterCalled = false;
  const activeKey = ['value that should not be used'];
  Object.defineProperty(activeKey, '0', {
    enumerable: true,
    get: testCase.step_func(() => {
      getterCalled = true;
      assert_throws_dom('TransactionInactiveError', () => {
        objectStore.get('key');
      }, 'transaction should not be active during key serialization');
      return 'value that should not be used';
    }),
  });
  cursor.continuePrimaryKey(activeKey, 0);
  await promiseForTransaction(testCase, transaction);
  db.close();

  assert_true(getterCalled,
    "activeKey's getter should be called during test");
}, 'Transaction inactive during key serialization in IDBCursor.continuePrimaryKey()');
```

</details>

Firefox does throw for `put`/`add`, though, which is why I originally scoped the fix to just that. Are you proposing that we handle `continue`/`continuePrimaryKey` in the spec despite Firefox's current behavior?

-- 
Reply to this email directly or view it on GitHub:
https://github.com/w3c/IndexedDB/pull/479#issuecomment-3449003544
You are receiving this because you are subscribed to this thread.

Message ID: <w3c/IndexedDB/pull/479/c3449003544@github.com>

Received on Sunday, 26 October 2025 23:17:53 UTC