Skip to content

reject with structured errors from the wasm bindings - #27

Open
fabracht wants to merge 3 commits into
mainfrom
wasm-structured-errors
Open

fabracht wants to merge 3 commits into
mainfrom
wasm-structured-errors

Conversation

@fabracht

Copy link
Copy Markdown
Contributor

Closes #25.

Problem

The wasm bindings rejected with a plain string (JsValue::from_str(e.to_string())), so JS consumers had to substring-match Display text — e.g. String(err).startsWith("conflict for") — to tell a unique-conflict from anything else. Fragile, and it breaks silently if the message wording changes.

Change

Every failed Store method now rejects with a structured JS Error:

  • stitch_err builds a js_sys::Error (message = the variant's Display) and attaches a stable kind plus entity/id for the variants that carry them, via Reflect::set.
  • error_parts maps every stitch::Error variant to a kind (conflict, ownership, notFound, timeout, connectionClosed, sessionInvalid, mqtt, mqdb, config, serde, io, notInitialized, alreadyInitialized, scopeNotActive, unknownEntity) — exhaustive, so a future Error variant won't compile until it's mapped.
  • The 34 self.inner.* call sites route through stitch_err; the serde/parse and non-serializable-input paths (JSON.stringify throwing on a BigInt/circular ref) carry kind: "invalidInput". No path rejects with a bare string.

Consumers can now write err.kind === "conflict" and delete their isUniqueViolation heuristic.

Breaking

Rejections change from strings to Error objects, so String(err) is now "Error: conflict for …". Callers matching the string must switch to err.kind/err.message. That makes it a minor bump — stitch-wasm 0.5.0 (left as [Unreleased] here; stitch-sync is untouched — the mapping lives entirely in the wasm crate).

Verification

  • wasm32 check + clippy clean, incl. two #[wasm_bindgen_test]s asserting the mapping (conflict → kind/entity/id/message; timeout → kind only; generic → invalidInput). Browser tests execute in CI.
  • Adversarial quorum (4 lenses + verify): surfaced one low finding — a non-serializable argument (BigInt/circular ref) rejected without a kind via JSON.stringify's raw throw — now fixed by routing it through invalidInput. Re-verified clean.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

wasm bindings should reject with a structured error (kind/entity/id), not a Display string

1 participant