Fix #46621 - include status code in cache (#47096)

Fixes #46621

As explained here https://github.com/vercel/next.js/issues/46621,

> Using fetch to retrieve data inside a page on server side, the
response status code is incorrect when simply loading/reloading the
page. It looks like nextjs is caching the response without taking into
account the status code.

In following code we do not add status code information to the cache. 

https://github.com/vercel/next.js/blob/canary/packages/next/src/server/lib/patch-fetch.ts#L189-L206

However we are accessing this status code in 

https://github.com/vercel/next.js/blob/canary/packages/next/src/server/lib/patch-fetch.ts#L247-L250

---------

Co-authored-by: JJ Kasper <jj@jjsweb.site>
This commit is contained in:
Talha Zekeriya Durmuş 2023-03-14 05:37:22 +01:00 committed by GitHub
parent 2579ad7648
commit 16131e2d49
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 46 additions and 0 deletions

View file

@ -195,6 +195,7 @@ export function patchFetch({
data: {
headers: Object.fromEntries(res.headers.entries()),
body: base64Body,
status: res.status,
},
revalidate,
},

View file

@ -50,6 +50,21 @@ createNextDescribe(
})
}
it('should include statusCode in cache', async () => {
const $ = await next.render$('/variable-revalidate/status-code')
const origData = JSON.parse($('#page-data').text())
expect(origData.status).toBe(404)
await check(async () => {
const new$ = await next.render$('/variable-revalidate/status-code')
const newData = JSON.parse(new$('#page-data').text())
expect(newData.status).toBe(origData.status)
expect(newData.text).not.toBe(origData.text)
return 'success'
}, 'success')
})
if (isNextStart) {
it('should output HTML/RSC files for static paths', async () => {
const files = (
@ -170,6 +185,9 @@ createNextDescribe(
'variable-revalidate/revalidate-3.html',
'variable-revalidate/revalidate-3.rsc',
'variable-revalidate/revalidate-3/page.js',
'variable-revalidate/status-code.html',
'variable-revalidate/status-code.rsc',
'variable-revalidate/status-code/page.js',
])
})
@ -374,6 +392,11 @@ createNextDescribe(
initialRevalidateSeconds: 3,
srcRoute: '/variable-revalidate/revalidate-3',
},
'/variable-revalidate/status-code': {
dataRoute: '/variable-revalidate/status-code.rsc',
initialRevalidateSeconds: 3,
srcRoute: '/variable-revalidate/status-code',
},
})
expect(curManifest.dynamicRoutes).toEqual({
'/blog/[author]/[slug]': {

View file

@ -0,0 +1,22 @@
export default async function Page() {
const data = await fetch(
'https://next-data-api-endpoint.vercel.app/api/random?status=404',
{
next: {
revalidate: 3,
},
}
).then(async (res) => {
return {
status: res.status,
text: await res.text(),
}
})
return (
<>
<p id="page">/variable-revalidate/status-code</p>
<p id="page-data">{JSON.stringify(data)}</p>
</>
)
}