Bypass rexie, surface real DOM errors and harden commit batching#10
Open
ssttuu wants to merge 2 commits into
Open
Bypass rexie, surface real DOM errors and harden commit batching#10ssttuu wants to merge 2 commits into
ssttuu wants to merge 2 commits into
Conversation
1 task
This release does three independent things, all motivated by the
user-visible "An IndexedDB error occured: idb error" failure reported
in surrealdb.js#571 / surrealist#1155 / indxdb#9 when calling
`db.use()` shortly after `db.connect('indxdb://...')`.
1. Wrap the underlying `idb` crate directly instead of going through
`rexie`. The `From<rexie::Error>` conversion only ever printed
"idb error" because `rexie::Error::IdbError` has no `{0}`
placeholder in its `Display` impl, so the inner DOMException name
and message were silently dropped before reaching the client. The
new `From<idb::Error>` impl pulls the `name`/`message` out of any
wrapped DOMException so callers see e.g. `InvalidStateError: A
request was placed against a transaction which is currently not
active` instead of the cryptic generic message.
2. Refactor `Transaction::commit()` to fire every buffered put and
delete through a single read-write IDB transaction, synchronously,
keeping only the most recently issued request handle. Only the last
request is awaited (the same pattern `idb::ObjectStore::put_all`
uses internally). Because no `.await` is interleaved with the
issuing loop, the IDB transaction's pending-request queue is never
empty during dispatch, so it cannot auto-commit prematurely. The
previous implementation awaited each `delete()` sequentially after
`put_all`, which the IDB spec does not guarantee will keep the
transaction active across the wake-up microtask boundary.
3. Add a `tests/web.rs` `wasm-bindgen-test` suite covering put/get
round-trips, mixed put+delete commits, multi-transaction sequences
(the shape of `db.use()`), savepoint rollback, read-your-own-writes
and conditional writes. Each test opens a freshly-named IDB
database so the suite is parallel-safe. CI runs the suite headless
under both Chrome and Firefox via `wasm-pack test`.
The public API is unchanged; the `rexie` dependency is dropped in
favour of `idb` directly.
Bumps the crate version to 0.13.0.
Made-with: Cursor
aa2841c to
2f45107
Compare
CI's stable rustfmt produces different output to my local environment because rustfmt.toml contains nightly-only options that get silently ignored on stable. Apply the stable formatter's output. Made-with: Cursor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What is the motivation?
End users (surrealdb/surrealdb.js#571, surrealdb/surrealist#1155, #9) hit a generic
InternalError: An IndexedDB error occured: idb errorthe first time they call
db.use(ns, db)afterdb.connect('indxdb://...')on@surrealdb/wasm3.0.x. The actualDOMException name and message never reach the user, making the
failure undebuggable. Investigating it surfaced a related concern
about how the
commit()flush dispatches mixed put + delete batches.What does this change do?
Bypass rexie, talk to
idbdirectly.rexie::Error::IdbError'sDisplayimpl is"idb error"with no{0}placeholder, so thewrapped
idb::Error(and the DOMException it carries) was alwaysdiscarded by the time it reached
From<rexie::Error> for indxdb::Error. Replacing the rexie indirection with a directidbintegration letsformat_idb_errorextract theDOMException's
nameandmessageso callers now seeInvalidStateError: A request was placed against a transaction which is currently not activeand similar -- the actual reasonthe IDB call failed.
Harden
Transaction::commit()'s flush phase. Every bufferedput and delete is now dispatched on a single fresh read-write
IDB transaction, synchronously, keeping only the last request
handle. Only that last request is awaited (mirroring the pattern
idb::ObjectStore::put_alluses internally). Because no.awaitis interleaved with the issuing loop, the IDB transaction's
pending-request queue is never empty during dispatch and the
transaction cannot auto-commit prematurely. The previous code
awaited each
delete()sequentially afterput_all, which theIDB spec does not guarantee keeps the transaction active across
the wake-up microtask boundary.
Browser regression tests + CI. A new
tests/web.rswasm-bindgen-testsuite covers put/get round-trips, mixedput+delete commits, multi-transaction sequences (the shape of
db.use()), savepoint rollback, read-your-own-writes andconditional writes. Each test opens a freshly-named IDB database
so the suite is parallel-safe. CI runs the suite headless under
both Chrome and Firefox via
wasm-pack test. `cargo clippy` isalso extended to `--all-targets` so test code is held to the
same standard as the library.
The public API is unchanged. The `rexie` dependency is dropped in
favour of `idb` directly. The crate version is bumped to `0.13.0`.
What is your testing strategy?
GitHub Actions testing -- the new `browser-test` matrix job runs the
`wasm-bindgen-test` suite headless under Chrome and Firefox. The
`mixed_put_delete_in_single_commit` and
`multi_transaction_use_simulation` cases are direct regressions for
the user-reported scenarios. Local `cargo check`,
`cargo clippy --all-targets --target wasm32-unknown-unknown` and
`cargo fmt --check` all pass.
Security Considerations
No security implications. The change is internal to the WASM-only
storage backend; no new untrusted inputs are accepted, and the error
formatting path only stringifies a `web_sys::DomException`'s
`name` and `message` properties (always-safe, browser-supplied
strings). The `rexie` dependency is dropped, reducing the
dependency surface.
Is this related to any issues?
Have you read the Contributing Guidelines?