[Fiber] Clean up ViewTransition when it fails to start (#34676)

The View Transition docs were unclear about this but apparently the
`finished` promise never settles if the animation never started. So if
there's an error that rejects the `ready` promise, we'll never run the
clean up which can cause it to stall.

Fixes #34662.

However, ultimately that is caused by Chrome stalling our default
`onDefaultTransitionIndicator` but it should be unblocked after 10
seconds, not a minute.
This commit is contained in:
Sebastian Markbåge
2025-10-01 21:58:13 -04:00
committed by GitHub
parent f7254efc5c
commit d74f061b69

View File

@@ -2279,6 +2279,11 @@ export function startViewTransition(
spawnedWorkCallback();
};
const handleError = (error: mixed) => {
// $FlowFixMe[prop-missing]
if (ownerDocument.__reactViewTransition === transition) {
// $FlowFixMe[prop-missing]
ownerDocument.__reactViewTransition = null;
}
try {
error = customizeViewTransitionError(error, false);
if (error !== null) {
@@ -2293,6 +2298,9 @@ export function startViewTransition(
layoutCallback();
// Skip afterMutationCallback() since we're not animating.
spawnedWorkCallback();
if (enableProfilerTimer) {
finishedAnimation();
}
}
};
transition.ready.then(readyCallback, handleError);
@@ -2699,6 +2707,11 @@ export function startGestureTransition(
? () => requestAnimationFrame(readyCallback)
: readyCallback;
const handleError = (error: mixed) => {
// $FlowFixMe[prop-missing]
if (ownerDocument.__reactViewTransition === transition) {
// $FlowFixMe[prop-missing]
ownerDocument.__reactViewTransition = null;
}
try {
error = customizeViewTransitionError(error, true);
if (error !== null) {
@@ -2713,6 +2726,9 @@ export function startGestureTransition(
// Skip readyCallback() and go straight to animateCallbck() since we're not animating.
// animateCallback() is still required to restore states.
animateCallback();
if (enableProfilerTimer) {
finishedAnimation();
}
}
};
transition.ready.then(readyForAnimations, handleError);