Conversation
📊 Package size report 1%↑
Show files (28 files)
🤖 This report was automatically generated by pkg-size-action |
megothss
force-pushed
the
error-boundaries
branch
from
March 10, 2026 03:19
df8288f to
35efe21
Compare
…ntegration tests Fixes the updating opcode integration so ErrorBoundaryOpcode is properly placed in the parent VM's updating list (not pushed onto the stack where it gets lost). Adds JS exception handling in UpdatingVM._execute with tracking frame rollback, executeGuarded() for sub-VM isolation, debug render tree rollback, and backflow assertion bypass in setError(). Includes 7 integration tests covering initial render, rerender, retry, nested boundaries, and missing error block.
Cache DOM boundaries before child opcodes execute so error recovery can clean up correctly even when inner TryOpcodes corrupt the bounds tree. Add beginBlock nextSibling parameter for proper insertion positioning. Add comprehensive integration tests for error boundary edge cases.
…OM refs Replace try-catch in evaluate() with unconditional snapshot + debug assertion, since bounds are always initialized. Null out cached DOM references after error recovery to avoid retaining detached nodes.
…ge.json The ember-template-compiler/index.js exposed dependency mapping was unintentionally removed in an earlier commit.
Replace vm.execute() with vm.executeGuarded() in nested VM contexts to prevent resetTracking() from destroying parent tracking frames. In DEBUG mode, AppendingVM.execute() calls resetTracking() on error, which wipes ALL tracking state including the parent UpdatingVM's frames. This made ErrorBoundary recovery impossible and caused "attempted to close a tracking frame" crashes. Fixes: - Backtracking assertions on tracked mutation after error recovery - Double-trigger tracking frame corruption (error → error → retry) - Error-in-error-block rendering failures bubbling incorrectly - ListBlockOpcode.insertItem tracking corruption when new items throw Changes: - TryOpcode.handleException(): use executeGuarded() so errors propagate cleanly to the UpdatingVM's catch handler without wiping tracking state - ErrorBoundaryOpcode.handleException(): restore tracking before re-render, use executeGuarded(), add robust DOM cleanup with lastPreviousSibling fallback for when inner TryOpcodes detach cached nodes via bounds.reset() - ErrorBoundaryOpcode.handleError(): restore tracking and consumed tags before transitioning to error state - ErrorBoundaryOpcode.transitionToError(): use executeGuarded(), add previousSibling-based DOM cleanup fallback, roll back debug render tree - ListBlockOpcode.insertItem(): use executeGuarded() - Add resetConsumedTags() to debug.ts to discard stale CONSUMED_TAGS entries after popping tracking frames during error recovery Adjusts assertion count in "readable error stack" test (7→6): the single outer console.error from UpdatingVM.execute() now captures full tracking info since the inner call no longer prematurely wipes it. Adds 5 regression tests covering all fix scenarios.
- Add handleError() to ExceptionHandler interface, removing unsafe `any` casts in UpdatingVMFrame.handleError() - Cast tagFor() results to UpdatableTag in ErrorBoundaryState.setError() to satisfy dirtyTag() parameter type - Cast array access in restoreTrackingTo() to fix Tracker | undefined not assignable to Tracker | null - Extract inline decorated class in test to fix "decorators are not valid here" TS error - Change defineSimpleHelper param from boolean to unknown to match expected signature - Remove unused imports (destroyChildren, clear) from component.ts - Run prettier on all modified files
ErrorBoundary should only be importable from @ember/component, matching the pattern of Input and Textarea. The value re-export was pulling 51 source files into type-tests compilation, causing 349 type errors.
The console.error logging is guarded by DEBUG in the source, so these tests can't pass in production builds.
A single modifier throwing during transaction.commit() previously aborted the entire loop, leaving all subsequently-scheduled modifiers uninstalled. Wrap each install/update in try-catch, collect the first error, and re-throw after all modifiers have been processed.
The DEBUG-only console.error tests bail early in production builds without ever setting this.component, causing the conditional runDestroy to be skipped and leaking Application namespaces.
…oundary The guarded opcode handler (VM_INVOKE_COMPONENT_LAYOUT_GUARDED_OP) created a sub-VM tree builder with nextSibling=null, causing content to be appended at the end of the parent element instead of at the parent VM's cursor position. This inverted the bounds delegation chain (firstNode after lastNode in DOM order), crashing clear() during route transitions. Fix: capture the parent tree builder's nextSibling before pushing the ResettableBlock and pass it to the sub-VM's tree builder. Also improves ErrorBoundaryOpcode.handleException to use direct DOM cleanup with cached node references instead of walking the delegation chain, and balances the parent tree builder's block stack with popBlock().
Track error boundary depth on the UpdatingVM so _execute() only pays the try-catch cost when inside an ErrorBoundary frame. Also reverts ListBlockOpcode.insertItem() to use execute() instead of executeGuarded().
…code - Make handleCaughtError required on ExceptionHandler interface - Add unreachable() stubs in TryOpcode and RenderResultImpl - Add clarifying comments for null end marker and resetPartial
- Add dropBlocks() to TreeBuilder: pops blocks without finalize() during
error cleanup, preventing placeholder comment leaks into remote elements
- Destroy sub-VM's destroyable root in executeGuarded catch path so
RemoteBlock destructors fire and clear orphaned remote DOM
- Guard RemoteBlock destructor against uninitialized bounds (error thrown
before any content rendered into the remote element)
- Add integration tests for {{#in-element}} inside ErrorBoundary (initial
render error + rerender error)
The previous commit introduced dropBlocks() for ErrorBoundary cleanup, but used it in executeGuarded which is also called by TryOpcode. TryOpcode needs popBlock/finalize to insert <!----> placeholders. Split into two methods: executeGuarded (popBlock) for TryOpcode, executeErrorBoundary (dropBlocks + destroy) for ErrorBoundary.
The PERF commit changed ListBlockOpcode.insertItem() from executeGuarded() to execute(), but executeGuarded is needed to clean up blocks/tracking when a list item throws inside an ErrorBoundary. Also fixes eslint non-null assertion and prettier formatting.
megothss
force-pushed
the
error-boundaries
branch
from
March 15, 2026 17:46
afbc7ec to
f752c7e
Compare
# Conflicts: # packages/@ember/component/index.ts # packages/@glimmer/runtime/lib/compiled/opcodes/component.ts # packages/@glimmer/runtime/lib/vm/append.ts # packages/@glimmer/runtime/lib/vm/update.ts
Upstream deleted defComponent and defineComponent from
internal-test-helpers when it unified the test infrastructure on
precompileTemplate. Rewrite all 72 call sites to the replacement idiom:
setComponentTemplate(
precompileTemplate(src, { strictMode: true, scope: () => ({ ... }) }),
templateOnly()
)
Templates that passed no scope stay non-strict, matching what the old
helper did with a null scope.
Open
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.
Adds the
<ErrorBoundary>component to Ember.js with full error recovery support.Key features:
<:default>for content,<:error>for fallback UI@retryWitharg for automatic error recovery when a tracked value changesconsole.errorlogging when errors are caughtTest coverage:
@retryWithwith primitives/arrays/objects/undefinedDemo app