[Fizz]: An error thrown without a Suspense boundary rejects the shell w/ no recovery primitive
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 5/5
- Thời gian dự kiến
- Hơn một tuần
- Mức phù hợp với người mới
- 30/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Cần làm rõ
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- javascript, nextjs, react
Hướng nghiên cứu
Bắt đầu với fizz-error-boundary-repro được liên kết và tái hiện việc shell bị từ chối bằng một component được render trên server mà không có Suspense boundary. Đọc các đường dẫn render phía server và xử lý lỗi Suspense trong Fizz, sau đó xác định phạm vi của một primitive khôi phục SSR được hỗ trợ. Hoàn thành khi lỗi có thể render một fallback cục bộ trong HTML của server mà không yêu cầu khôi phục phía client.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
React version: 19.3.0
Steps To Reproduce
- Render a server (or ssr) component with zero
Suspenseboundaries throw new Error()or next'snotFound()- 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.
- Ngôn ngữ chính
- JavaScript
- Star
- 251k
- Fork
- 51.4k
- Merge trung bình
- 2 ngày 4 giờ
- Pull request đã merge (30 ngày)
- 50
Hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của react/react
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 74/100
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
palladius/rails8-app-on-gcp#145 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
dotenvx/dotenv-vscode#139 ·
-
test-change-proposal
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
web-platform-tests/interop#1455 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
corsairdev/corsair#1764 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100