fix(nuxt): avoid throwing 404 error before middleware finishes (#29054)

This commit is contained in:
Ryota Watanabe 2024-10-09 07:09:02 +09:00 committed by GitHub
parent 9797483e61
commit ebc370c6f6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 26 additions and 16 deletions

View File

@ -148,16 +148,8 @@ const plugin: Plugin<{ router: Router }> = defineNuxtPlugin({
if (import.meta.server && failure?.type === 4 /* ErrorTypes.NAVIGATION_ABORTED */) { if (import.meta.server && failure?.type === 4 /* ErrorTypes.NAVIGATION_ABORTED */) {
return return
} }
if (to.matched.length === 0) {
await nuxtApp.runWithContext(() => showError(createError({ if (import.meta.server && to.redirectedFrom && to.fullPath !== initialURL) {
statusCode: 404,
fatal: false,
statusMessage: `Page not found: ${to.fullPath}`,
data: {
path: to.fullPath,
},
})))
} else if (import.meta.server && to.redirectedFrom && to.fullPath !== initialURL) {
await nuxtApp.runWithContext(() => navigateTo(to.fullPath || '/')) await nuxtApp.runWithContext(() => navigateTo(to.fullPath || '/'))
} }
}) })
@ -252,6 +244,19 @@ const plugin: Plugin<{ router: Router }> = defineNuxtPlugin({
await nuxtApp.callHook('page:loading:end') await nuxtApp.callHook('page:loading:end')
}) })
router.afterEach(async (to, _from) => {
if (to.matched.length === 0) {
await nuxtApp.runWithContext(() => showError(createError({
statusCode: 404,
fatal: false,
statusMessage: `Page not found: ${to.fullPath}`,
data: {
path: to.fullPath,
},
})))
}
})
nuxtApp.hooks.hookOnce('app:created', async () => { nuxtApp.hooks.hookOnce('app:created', async () => {
try { try {
// #4920, #4982 // #4920, #4982

View File

@ -167,8 +167,7 @@ describe('pages', () => {
expect(headers.get('location')).toEqual('/') expect(headers.get('location')).toEqual('/')
}) })
// TODO: https://github.com/nuxt/nuxt/pull/29054 it('allows routes to be added dynamically', async () => {
it.todo('allows routes to be added dynamically', async () => {
const html = await $fetch<string>('/add-route-test') const html = await $fetch<string>('/add-route-test')
expect(html).toContain('Hello Nuxt 3!') expect(html).toContain('Hello Nuxt 3!')
}) })
@ -250,8 +249,7 @@ describe('pages', () => {
await serverPage.close() await serverPage.close()
}) })
it.todo('returns 500 when there is an infinite redirect', async () => { it.runIf(isDev())('returns 500 when there is an infinite redirect', async () => {
// TODO: Fix infinite redirect without catchall
const { status } = await fetch('/catchall/redirect-infinite', { redirect: 'manual' }) const { status } = await fetch('/catchall/redirect-infinite', { redirect: 'manual' })
expect(status).toEqual(500) expect(status).toEqual(500)
}) })
@ -274,8 +272,7 @@ describe('pages', () => {
await expectNoClientErrors('/catchall/not-found') await expectNoClientErrors('/catchall/not-found')
}) })
// TODO: https://github.com/nuxt/nuxt/pull/29054 it('should render correctly when loaded on a different path', async () => {
it.todo('should render correctly when loaded on a different path', async () => {
const { page, pageErrors } = await renderPage() const { page, pageErrors } = await renderPage()
await page.goto(url('/proxy')) await page.goto(url('/proxy'))
await page.waitForFunction(() => window.useNuxtApp?.() && !window.useNuxtApp?.().isHydrating) await page.waitForFunction(() => window.useNuxtApp?.() && !window.useNuxtApp?.().isHydrating)
@ -1278,6 +1275,13 @@ describe('middlewares', () => {
expect(html).toContain('Hello Nuxt 3!') expect(html).toContain('Hello Nuxt 3!')
}) })
it('should allow redirection from a non-existent route with `ssr: false`', async () => {
const page = await createPage('/redirect/catchall')
expect(await page.getByRole('heading').textContent()).toMatchInlineSnapshot('"[...slug].vue"')
await page.close()
})
it('should allow aborting navigation on server-side', async () => { it('should allow aborting navigation on server-side', async () => {
const res = await fetch('/?abort', { const res = await fetch('/?abort', {
headers: { headers: {

View File

@ -62,6 +62,7 @@ export default defineNuxtConfig({
}, },
routeRules: { routeRules: {
'/route-rules/spa': { ssr: false }, '/route-rules/spa': { ssr: false },
'/redirect/catchall': { ssr: false },
'/head-spa': { ssr: false }, '/head-spa': { ssr: false },
'/route-rules/middleware': { appMiddleware: 'route-rules-middleware' }, '/route-rules/middleware': { appMiddleware: 'route-rules-middleware' },
'/hydration/spa-redirection/**': { ssr: false }, '/hydration/spa-redirection/**': { ssr: false },