Xunnamius/next-test-api-route-handler

Recursive redirection occurs when redirecting within the handler

snaka opened this issue ยท 3 comments

snaka commented

Note:
This is not a problem caused by this library itself, but rather an issue that can arise when using the library. It is being documented as an issue with the intention of highlighting potential problems that may occur when using the library, and to request its inclusion in the documentation.

Overview of the Issue

When redirecting within an API handler, if you simply call fetch() in the test, it recursively triggers redirection. As a result, an error stating redirect count exceeded occurs.

Reproduction Test Code

  test('redirect', async () => {
    await testApiHandler({
      pagesHandler: (_, res) => res.redirect(302, '/'),
      test: async ({ fetch }) => {
        const res = await fetch({ method: 'GET' })
        expect(res.redirected).toBeTruthy()
      }
    })
  })

Executing this code results in the following error:

    TypeError: fetch failed

       8 |       pagesHandler: (_, res) => res.redirect(302, '/'),
       9 |       test: async ({ fetch }) => {
    > 10 |         const res = await fetch({ method: 'GET' })
         |                     ^
      11 |         expect(res.redirected).toBeTruthy()
      12 |       }
      13 |     })

(snip)

    Cause:
    redirect count exceeded

      at async node:internal/deps/undici/undici:10342:20
      at async node:internal/deps/undici/undici:10342:20
      at async node:internal/deps/undici/undici:10342:20
      (The above line repeats)

Solution Approach

By adding redirect: 'manual' when calling fetch(), it prevents automatic redirection to the redirect destination, allowing validation of the response.

Updated test code:

  test.skip('redirect', async () => {
    await testApiHandler({
      pagesHandler: (_, res) => res.redirect(302, '/'),
      test: async ({ fetch }) => {
        const res = await fetch({ method: 'GET', redirect: 'manual' })
        expect(res.status).toEqual(302)
        expect(res.headers.get('location')).toEqual('/')
      }
    })
  })

See also: https://developer.mozilla.org/en-US/docs/Web/API/fetch#redirect

Expected Fix

To prevent similar issues in the future, it would be beneficial to explicitly mention this in the documentation.

Thanks for the heads up. That's interesting, it may be a undici thing since I've tested redirects with the pages router back when NTARH used the old node-fetch. I'll investigate and update the docs accordingly.

snaka commented

My next info outputs is as follows

Operating System:
  Platform: linux
  Arch: x64
  Version: #1 SMP Fri Jan 27 02:56:13 UTC 2023
Binaries:
  Node: 20.11.0
  npm: 10.2.4
  Yarn: 1.22.21
  pnpm: N/A
Relevant Packages:
  next: 14.0.4
  eslint-config-next: 14.0.4
  react: 18.2.0
  react-dom: 18.2.0
  typescript: 5.3.3
Next.js Config:
  output: N/A

๐ŸŽ‰ This issue has been resolved in version 4.0.4 ๐ŸŽ‰

The release is available on:

Your semantic-release bot ๐Ÿ“ฆ๐Ÿš€