@remotion/studio: Errors inside composition don't go fullscreen anymore#6962
@remotion/studio: Errors inside composition don't go fullscreen anymore#6962JonnyBurger merged 2 commits intomainfrom
@remotion/studio: Errors inside composition don't go fullscreen anymore#6962Conversation
Instead of the whole app unmounting when a composition throws a render error, catch it with an error boundary inside <Composition>'s portal. The error is forwarded via context to CanvasOrLoading which displays it in the canvas area using the existing ErrorLoader UI. React Fast Refresh automatically resets the boundary when the errored component is fixed. Closes #6704 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Reviewed PR #6962. Submitted feedback on Task list (5/5 completed)
|
@remotion/studio: Errors inside composition don't go fullscreen anymore
There was a problem hiding this comment.
Clean design — two contexts bridge core ↔ studio nicely. One potential correctness issue with the error boundary's clear lifecycle.
Big Pickle (free) | 𝕏
| componentDidUpdate(_prevProps: Props): void { | ||
| if (!this.state.hasError) { | ||
| this.props.onClear(); | ||
| } | ||
| } |
There was a problem hiding this comment.
componentDidUpdate is not called on initial mount — only componentDidMount is. This means onClear is never called when:
- Switching compositions: the old (errored) boundary unmounts without clearing the error (no
componentWillUnmounthandler), and the new boundary's first render triggerscomponentDidMount, notcomponentDidUpdate. The stale error persists inEditor's state until the new boundary happens to re-render. - HMR recovery: React Fast Refresh remounts error boundaries in an error state, creating a fresh instance. Same issue —
componentDidMountfires, notcomponentDidUpdate.
In practice the gap may be very short (the next child re-render triggers componentDidUpdate → onClear), but the error overlay will flash briefly in the canvas between mount and the first update.
Fix: also call onClear in componentDidMount.
componentDidMount(): void {
if (!this.state.hasError) {
this.props.onClear();
}
}This is cheap (it's a no-op setRenderError(null) when there's no error) and closes the gap.
| } | ||
|
|
||
| componentDidUpdate(_prevProps: Props): void { | ||
| if (!this.state.hasError) { |
There was a problem hiding this comment.
Calling onClear on every update when hasError is false (not just the error→clear transition) is noisy — every prop/child re-render triggers it. It's technically harmless since setRenderError(null) bails out when already null, but the previous prevState.hasError && !this.state.hasError check was more precise. Was there a specific reason for broadening this? If it was to handle the HMR recovery case, componentDidMount (see above) would be a more targeted fix.

Summary
<Composition>'s portal (Studio only)ErrorLoaderUI, while the rest of the Studio (timeline, sidebar, controls) stays aliveCloses #6704
Test plan
trimBefore={-20}on a<Video>) to a composition🤖 Generated with Claude Code