You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
withResult: no call site passes onException, so non-Error throws lose their message repo-wide #743
withResult discards the detail of any non-Error throw, because no call site in the repo supplies the hook that would preserve it.
The mechanism
@byteslice/result@0.2.0, dist/result.js:
functionensureError(ex){returnexinstanceofError ? ex : newError("Something went wrong");}asyncfunctionwithResult(operation,onError,hooks){try{return{data: awaitoperation()};}catch(ex){consterror=hooks?.onException?.(ex)??ensureError(ex);return{failure: onError(error)};}}
ensureError is only the fallback. The third parameter — hooks?: { onException?: (ex: unknown) => Error } — receives the raw exception and takes precedence.
So every withResult in the repo silently converts a non-Error rejection into Error("Something went wrong"), and the onError mapper — e.g. (error as Error).message in the native operations — faithfully records the boilerplate.
Impact
Wherever a non-Error value can be thrown, the failure message a caller sees is "Something went wrong" with no way to recover what actually happened. It is not a hypothetical shape: packages/stack/src/dynamodb/operations/* explicitly notes that "withResult'sensureErrorwraps non-Error objects", which is why those paths hand-roll throwPreservingCode to keep the FFI code alive.
Most acute at any WASM/FFI boundary — see the fix already landed for wasm-inline in #741, where wasm-bindgen rejects with the raw JsValue and the WASM build exports no ProtectError class, so real failures genuinely arrive as bare strings or objects.
Fix
Pass onException at the withResult call sites, converting without losing the value — roughly what wasm-inline.ts's toError now does:
Worth doing once as a shared helper rather than per call site — the omission is invisible (it does not fail a build, it just degrades messages), so a single seam that binds the hook is what stops it recurring.
Update @byteslice/result 0.2.0 → latest (0.5.0) #532 — bumping @byteslice/result 0.2.0 → 0.5.0 may change ensureError's default, but passing onException is correct regardless and does not depend on that landing.
Activity