Repository navigation
fix(bindings): keep the error chain when a binding error reaches TypeScript (ALIEN-1249) - #910
Merged
ItamarZand88 merged 2 commits intoOct 6, 2026
Conversation
…Script (ALIEN-1249)
|
ItamarZand88
deleted the
itamar/alien-1249-the-node-bindings-drop-a-sandbox-errors-cause-so-a-refusal
branch
October 6, 2026 15:04
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.
Summary
A binding error that reaches TypeScript now keeps the error that caused it. Before this, a sandbox refusal said "the cause carries which side refused", but the JS error arrived with
sourceandcauseboth undefined.When a binding call fails in a Node app:
AlienErrorwhosesourceholds the chain, for example the cloud's own HTTP response underSANDBOX_COMMAND_FAILED.source.unwrapNapiErrorpassessourceto the TypeScriptAlienError, which rebuilds the chain.This PR changes the envelope from code-and-message-only to code, message and cause chain.
What was broken
ErrorEnvelopeinalien-bindings-nodehad nosourcefield, andunwrapNapiErrornever passed one, so both sides dropped the chain.What I did
sourceto the envelope. It is the error's existing chain, serialized the wayAlienErrorserializes everywhere else. The TypeScriptAlienErrorschema is generated from that same struct.unwrapNapiErrorpassesenvelope.sourcethrough, and the TypeScript constructor rebuilds the nested sources.AlienErrorconstructor in@alienplatform/corebuilds the source beforesuperand passes that same object ascause. Before this,causeheld the raw serialized object, so code that followsError.causesaw a plain object.internalflag, sotoExternal()still hides internal layers one by one.How I tested
a_wrapped_error_reaches_typescript_with_the_error_that_caused_it. It failed before the change (env["source"]wasNull) and passes after. It also checks the inner layer'sinternalandretryable.unwrapNapiErrorwith a two-level chain. It failed before the change (expected undefined to be 'HTTP_RESPONSE_ERROR') and passes after. It also checkserr.cause === err.source.cargo test -p alien-bindings-node --lib: 33 passed.packages/bindingsunit tests: 73 passed.packages/coretests: 178 passed.tsc --noEmitis clean. The full bindings suite against the real addon: 133 passed.Safe because only the in-process error gains a field. The SDK and command runtimes still forward only
error.message, which is unchanged (packages/sdk/src/worker-runtime/event-loop.ts:34,packages/commands/src/receiver.ts:540). Proven by the real-addon suite above, which still passes unchanged.