[Fizz]: An error thrown without a Suspense boundary rejects the shell w/ no recovery primitive

Abierto
#37,616 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
5/5
Tiempo estimado
Más de una semana
Aptitud para principiantes
30/100
Tipo de issue
Error
Claridad
Necesita aclaración
Estado de actividad
Activo
Stack tecnológico
javascript, nextjs, react
Área
backend, frontend

Línea de trabajo

Comienza con el fizz-error-boundary-repro enlazado y reproduce el rechazo del shell usando un componente renderizado en el servidor sin un límite de Suspense. Lee las rutas de renderizado en el servidor y de manejo de errores de Suspense en Fizz, y determina después el alcance de un primitive de recuperación de SSR compatible. Se considera terminado cuando el fallo puede renderizar un fallback local en el HTML del servidor sin requerir recuperación en el cliente.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

Status: Unconfirmed

React version: 19.3.0

Steps To Reproduce

  1. Render a server (or ssr) component with zero Suspense boundaries
  2. throw new Error() or next's notFound()
  3. Fizz's shell rejects, on nextjs this returns empty html and the client re-renders into an error boundary

This is reproducibly verified on my nextjs site (easier to see with JS disabled):

https://popflash.site/fooobar => 404 html properly rendered because the route doesnt match anything

https://popflash.site/user/129388712 => blank page, client rendered because this user id doesnt exist (/user/[id]/page.tsx) => calls notFound()

Link to code example:

A very basic, claude/codex-driven fizz only example:

https://github.com/switz/fizz-error-boundary-repro

The current behavior

Forgive my naive understanding, but here goes my attempt: an error thrown during Flight gets serialized as an error row at that node, and then rethrown (on the server Fizz, on the client Fiber: where an ErrorBoundary can catch it) – the only thing that can contain it in Fizz is Suspense. Suspense catches the error and emits its fallback's HTML on the server.

When there is no Suspense boundary to catch the error, the shell aborts. So here, Suspense is actually performing two tasks – shell deferral and error catching, which actually compete on functionality (if an error arrives after the response has committed, the framework can no longer control the status code). In an ideal world, there would be another mechanism for catching errors and providing fallbacks, similar to ErrorBoundary, but for SSR.

I have walked through a few potential solutions (e.g. a new <CatchBoundary>?), but don't want to get ahead of myself by suggesting them in earnest. I'm curious if this is an issue that resonates with the team. If so, happy to work with you to find the right solve.

Ideally, an error in a nested component could render a fallback at an enclosing boundary while preserving the surrounding layout.
For errors encountered before response commits, the fallback would be included in the server-rendered HTML, and the framework could choose the appropriate HTTP status. This would avoid requiring a second full HTML render or client-side recovery.

Expected behavior

A supported way to recover locally from errors during SSR without introducing a Suspense boundary.

Edit: This could be a new native <ErrorBoundary /> component that react ships that handles errors across both the server and client. I ran a pass at implementing it and it works well - going to play with it more before submitting a PR, but happy to chat more if this is something the team is open to considering.

Lenguaje dominante
JavaScript
Estrellas
251k
Forks
51.4k
Merge medio
2 d 1 h
PR fusionados (30 d)
51

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de react/react

Todos los issues de react/react

Issues similares

Más issues de JavaScript

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.