Skip to content

[Fizz] Track abort state on Request#36583

Merged
gnoff merged 1 commit into
facebook:mainfrom
gnoff:jstory/model-abort-on-request
May 31, 2026
Merged

[Fizz] Track abort state on Request#36583
gnoff merged 1 commit into
facebook:mainfrom
gnoff:jstory/model-abort-on-request

Conversation

@gnoff
Copy link
Copy Markdown
Collaborator

@gnoff gnoff commented May 31, 2026

Previously Fizz represented an active abort using the ABORTING request status. This is ambiguous because aborting a task can synchronously fatal the request, transitioning it to CLOSING or CLOSED while another task is still unwinding from the same abort. Once that happened, the in-flight task no longer observed that the request was aborted and could fail to report its abort error.

This change removes the ABORTING status and instead tracks whether the request was aborted independently on the Request. The existing fatalError field continues to store the abort reason. As a result, tasks that were rendering when an abort occurred continue to observe the abort even if another aborted task has already fataled the request, allowing all relevant unfinished task errors to be reported. DEV stalled replays temporarily mask the aborted state so they can continue to reconstruct suspended call sites as before.

This also establishes explicit abort state on the Request for follow-up work that delays abort completion and allows rejected suspended work to provide more specific abort errors.

@meta-cla meta-cla Bot added the CLA Signed label May 31, 2026
@gnoff gnoff requested review from eps1lon and unstubbable May 31, 2026 17:21
@github-actions github-actions Bot added the React Core Team Opened by a member of the React Core Team label May 31, 2026
Previously Fizz represented an active abort using the `ABORTING` request status. This is ambiguous because aborting a task can synchronously fatal the request, transitioning it to `CLOSING` or `CLOSED` while another task is still unwinding from the same abort. Once that happened, the in-flight task no longer observed that the request was aborted and could fail to report its abort error.

This change removes the `ABORTING` status and instead tracks whether the request was aborted independently on the Request. The existing `fatalError` field continues to store the abort reason. As a result, tasks that were rendering when an abort occurred continue to observe the abort even if another aborted task has already fataled the request, allowing all relevant unfinished task errors to be reported. DEV stalled replays temporarily mask the aborted state so they can continue to reconstruct suspended call sites as before.

This also establishes explicit abort state on the Request for follow-up work that delays abort completion and allows rejected suspended work to provide more specific abort errors.
@gnoff gnoff force-pushed the jstory/model-abort-on-request branch from 74138e5 to 6e6fdaf Compare May 31, 2026 17:21
@react-sizebot
Copy link
Copy Markdown

Comparing: 05ca66a...6e6fdaf

Critical size changes

Includes critical production bundles, as well as any change greater than 2%:

Name +/- Base Current +/- gzip Base gzip Current gzip
oss-stable/react-dom/cjs/react-dom.production.js = 6.84 kB 6.84 kB = 1.88 kB 1.88 kB
oss-stable/react-dom/cjs/react-dom-client.production.js = 614.26 kB 614.26 kB = 108.57 kB 108.57 kB
oss-experimental/react-dom/cjs/react-dom.production.js = 6.84 kB 6.84 kB = 1.88 kB 1.88 kB
oss-experimental/react-dom/cjs/react-dom-client.production.js = 680.19 kB 680.19 kB = 119.51 kB 119.51 kB
facebook-www/ReactDOM-prod.classic.js = 700.61 kB 700.61 kB = 123.09 kB 123.09 kB
facebook-www/ReactDOM-prod.modern.js = 690.93 kB 690.93 kB = 121.48 kB 121.48 kB

Significant size changes

Includes any change greater than 0.2%:

(No significant changes)

Generated by 🚫 dangerJS against 6e6fdaf

@gnoff gnoff merged commit ddcb58f into facebook:main May 31, 2026
237 checks passed
@gnoff gnoff deleted the jstory/model-abort-on-request branch May 31, 2026 20:48
github-actions Bot pushed a commit that referenced this pull request May 31, 2026
Previously Fizz represented an active abort using the `ABORTING` request
status. This is ambiguous because aborting a task can synchronously
fatal the request, transitioning it to `CLOSING` or `CLOSED` while
another task is still unwinding from the same abort. Once that happened,
the in-flight task no longer observed that the request was aborted and
could fail to report its abort error.

This change removes the `ABORTING` status and instead tracks whether the
request was aborted independently on the Request. The existing
`fatalError` field continues to store the abort reason. As a result,
tasks that were rendering when an abort occurred continue to observe the
abort even if another aborted task has already fataled the request,
allowing all relevant unfinished task errors to be reported. DEV stalled
replays temporarily mask the aborted state so they can continue to
reconstruct suspended call sites as before.

This also establishes explicit abort state on the Request for follow-up
work that delays abort completion and allows rejected suspended work to
provide more specific abort errors.

DiffTrain build for [ddcb58f](ddcb58f)
gnoff added a commit that referenced this pull request May 31, 2026
Stacked on #36583

Fizz previously identified a task that was rendering during an abort by
marking its blocked Segment as `RENDERING`. This does not work for
resumed replay tasks because they do not have a Segment, so an abort
during replay could eagerly abort the task before it unwound and then
report the internal `null` throw instead of the abort reason.

Track the task currently executing on the Request so aborting can leave
the in-flight task to unwind through its normal error path for both
render and replay tasks. Since this replaces the only purpose of the
Segment `RENDERING` status, remove that status and its associated
bookkeeping.

When resumed work unwinds after aborting, use the request's abort reason
in the replay catch paths so aborting while replaying a prerendered tree
or while rendering a resumed segment reports the meaningful abort reason
instead of the internal control-flow value.
github-actions Bot pushed a commit that referenced this pull request May 31, 2026
Stacked on #36583

Fizz previously identified a task that was rendering during an abort by
marking its blocked Segment as `RENDERING`. This does not work for
resumed replay tasks because they do not have a Segment, so an abort
during replay could eagerly abort the task before it unwound and then
report the internal `null` throw instead of the abort reason.

Track the task currently executing on the Request so aborting can leave
the in-flight task to unwind through its normal error path for both
render and replay tasks. Since this replaces the only purpose of the
Segment `RENDERING` status, remove that status and its associated
bookkeeping.

When resumed work unwinds after aborting, use the request's abort reason
in the replay catch paths so aborting while replaying a prerendered tree
or while rendering a resumed segment reports the meaningful abort reason
instead of the internal control-flow value.

DiffTrain build for [de8e005](de8e005)
github-actions Bot pushed a commit to code/lib-react that referenced this pull request Jun 1, 2026
Stacked on facebook#36583

Fizz previously identified a task that was rendering during an abort by
marking its blocked Segment as `RENDERING`. This does not work for
resumed replay tasks because they do not have a Segment, so an abort
during replay could eagerly abort the task before it unwound and then
report the internal `null` throw instead of the abort reason.

Track the task currently executing on the Request so aborting can leave
the in-flight task to unwind through its normal error path for both
render and replay tasks. Since this replaces the only purpose of the
Segment `RENDERING` status, remove that status and its associated
bookkeeping.

When resumed work unwinds after aborting, use the request's abort reason
in the replay catch paths so aborting while replaying a prerendered tree
or while rendering a resumed segment reports the meaningful abort reason
instead of the internal control-flow value.

DiffTrain build for [de8e005](facebook@de8e005)
github-actions Bot pushed a commit to srpatcha/react that referenced this pull request Jun 1, 2026
Stacked on facebook#36583

Fizz previously identified a task that was rendering during an abort by
marking its blocked Segment as `RENDERING`. This does not work for
resumed replay tasks because they do not have a Segment, so an abort
during replay could eagerly abort the task before it unwound and then
report the internal `null` throw instead of the abort reason.

Track the task currently executing on the Request so aborting can leave
the in-flight task to unwind through its normal error path for both
render and replay tasks. Since this replaces the only purpose of the
Segment `RENDERING` status, remove that status and its associated
bookkeeping.

When resumed work unwinds after aborting, use the request's abort reason
in the replay catch paths so aborting while replaying a prerendered tree
or while rendering a resumed segment reports the meaningful abort reason
instead of the internal control-flow value.

DiffTrain build for [de8e005](facebook@de8e005)
github-actions Bot pushed a commit to srpatcha/react that referenced this pull request Jun 1, 2026
Stacked on facebook#36583

Fizz previously identified a task that was rendering during an abort by
marking its blocked Segment as `RENDERING`. This does not work for
resumed replay tasks because they do not have a Segment, so an abort
during replay could eagerly abort the task before it unwound and then
report the internal `null` throw instead of the abort reason.

Track the task currently executing on the Request so aborting can leave
the in-flight task to unwind through its normal error path for both
render and replay tasks. Since this replaces the only purpose of the
Segment `RENDERING` status, remove that status and its associated
bookkeeping.

When resumed work unwinds after aborting, use the request's abort reason
in the replay catch paths so aborting while replaying a prerendered tree
or while rendering a resumed segment reports the meaningful abort reason
instead of the internal control-flow value.

DiffTrain build for [de8e005](facebook@de8e005)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed React Core Team Opened by a member of the React Core Team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants