Something [between `11.0.2-canary.5` and `11.0.2-canary.6`](https://github.com/vercel/next.js/compare/v11.0.2-canary.5...v11.0.2-canary.6) changed the behavior that logged any runtime errors in `getStaticProps` to stderr. This is only observable if `getStaticProps` has a `revalidate` value, and the build did not fail. The error has to happen in a subsequent revalidation step.
This PR reverts the change and fixes#30375.
## Bug
- [x] Related issues linked using `fixes #number`
- [x] Integration tests added
- [ ] Errors have helpful link attached, see `contributing.md`
## Feature
- [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`
## Documentation / Examples
- [ ] Make sure the linting passes by running `yarn lint`
Co-authored-by: JJ Kasper <22380829+ijjk@users.noreply.github.com>
We're no longer currently planning on supporting caching for dynamic responses, so we can do some cleaning & simplification:
* Multiplexing can be removed since we only ever subscribe once (via `RenderResult.pipe`, described below)
* `RenderResult.toUnchunkedString` can become synchronous since static responses are never chunked
* `RenderResult.forEach` can become `RenderResult.pipe` which helps encapsulate some of the details of `RenderResult`
Our `Observable` use has gotten sufficiently complex that it makes sense to just use a 3rd party implementation and not worry about maintaining it ourselves. As a bonus, it doesn't rely on Node APIs.
Adds `RenderResult`, replacing the `string` that `renderToHTML` used to return, with an `Observable`-like API that callers can use to subscribe and get a callback when chunks are available to flush, etc.
This is the last architectural change needed for streaming. There are, however, other things currently standing in the way of streaming. For example, it is common to mutate `res` in `getServerSideProps` to do routing work, or write headers, before fetching page data. This pattern effectively nullifies any advantages of streaming. I may do a follow-up PR that adds an experimental alternative for applications not using React 18, but the main purpose for this support is for Suspense and Server Components.
For that reason, there's no actual streaming here yet: instead we just flush a single chunk. A follow-up PR will add support for streaming suspense boundaries in React 18.
It's possible for `renderToHTML` to return `null` if `res.finished || res.headersSent` is `true` after `getInitialProps` or `getServerSideProps`. In such cases, we can't generate a valid `ResponseCacheEntry` or `ResponsePayload`, so we shouldn't try.
I took the opportunity to add an invariant for when we expected a cacheable response, but didn't get one. This could happen because Next.js or an application erroneously mutated the underlying `res` during the rendering of a page with `getStaticProps`. This shouldn't normally be possible because `res` isn't exposed in such cases, but it's theoretically possible with a custom server, so it seemed worth flagging.
By itself, `withCoalescedInvoke` with a separate `this.incrementalCache.set(...)` isn't really suitable for streaming responses. Since streaming is asynchronous, updating the cache separately introduces a gap where another origin request for the same resource could be made.
This could potentially be addressed by moving the cache update, but then `IncrementalCache` itself would need to be made to support streaming, in addition to the many other responsibilities it has. In this case, it seemed best to just use composition to add another caching layer in front of it, which is a familiar and understandable concept. Eventually, we might want to move this cache to the HTTP layer, which will also be simpler with this change.
As an added bonus, `renderToResponseWithComponents` becomes significantly simpler, and we delete some duplication.