admin管理员组文章数量:1134549
My /app/api/auth/route.ts
file:
import { redirect } from 'next/navigation';
export async function GET(req: Request) {
try {
redirect('/dashboard');
} catch (error) {
console.log(error);
redirect('/');
}
}
I realized that when I do redirect in a try catch, I get the error :
Error: NEXT_REDIRECT
at getRedirectError (webpack-internal:///(sc_server)/./node_modules/next/dist/client/components/redirect.js:40:19)
at redirect (webpack-internal:///(sc_server)/./node_modules/next/dist/client/components/redirect.js:46:11)
at GET (webpack-internal:///(sc_server)/./app/api/auth/route.ts:23:66)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async eval (webpack-internal:///(sc_server)/./node_modules/next/dist/server/future/route-modules/app-route/module.js:244:37) {
digest: 'NEXT_REDIRECT;replace;/dashboard'
}
When I get get rid of the try catch everything works fine:
export async function GET(req: Request) {
redirect('/dashboard')
}
This works as expected. I need try and catch because this is an auth route and I need some error handling because the request could fail, I have left out the auth functionalities because I realized that this happens just on a simple try and catch.
Or if Next 13 has another way of error handling in /api
routes please let me know.
My /app/api/auth/route.ts
file:
import { redirect } from 'next/navigation';
export async function GET(req: Request) {
try {
redirect('/dashboard');
} catch (error) {
console.log(error);
redirect('/');
}
}
I realized that when I do redirect in a try catch, I get the error :
Error: NEXT_REDIRECT
at getRedirectError (webpack-internal:///(sc_server)/./node_modules/next/dist/client/components/redirect.js:40:19)
at redirect (webpack-internal:///(sc_server)/./node_modules/next/dist/client/components/redirect.js:46:11)
at GET (webpack-internal:///(sc_server)/./app/api/auth/route.ts:23:66)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async eval (webpack-internal:///(sc_server)/./node_modules/next/dist/server/future/route-modules/app-route/module.js:244:37) {
digest: 'NEXT_REDIRECT;replace;/dashboard'
}
When I get get rid of the try catch everything works fine:
export async function GET(req: Request) {
redirect('/dashboard')
}
This works as expected. I need try and catch because this is an auth route and I need some error handling because the request could fail, I have left out the auth functionalities because I realized that this happens just on a simple try and catch.
Or if Next 13 has another way of error handling in /api
routes please let me know.
20 Answers
Reset to default 60When using redirect
in a server component you should move it to the finally
block. Here is how:
export default async function Page() {
let redirectPath: string | null = null
try {
//Rest of the code
redirectPath = `/dashboard`
} catch (error) {
//Rest of the code
redirectPath = `/`
} finally {
//Clear resources
if (redirectPath)
redirect(redirectPath)
}
return <>{/*Rest of JSX*/}</>
}
From the redirect documentation:
redirect
internally throws an error so it should be called outside oftry/catch
blocks.
In api routes
you should use the NextResponse
from next/server
. Here is how
import { NextRequest, NextResponse } from "next/server";
export function GET(request: NextRequest) {
try {
//Code
return NextResponse.redirect(`<an absolute url>`)
} catch {
//Error handling code
return NextResponse.redirect(`<an absolute url>`)
} finally {
//Clear resources
//No redirect here
}
}
At the moment, the workaround I found is to not use:
import { redirect } from 'next/navigation';
But to use instead:
import { useRouter } from 'next/navigation'
const router = useRouter()
router.push("/")
It's easy to fix it. Currently, there is a bug in try-catch
block with Next redirect. But you don't need to change anything. You just need to transfer try-catch
block to different function. I can give you an example of my code:
"use server";
import LoginSchema from "@/Schemas/LoginSchema";
import PocketBase from "pocketbase";
import { redirect } from "next/navigation";
const analyze = async (data) => {
const pb = new PocketBase("http://127.0.0.1:8090");
try {
const authData = await pb
.collection("UserTable")
.authWithPassword(await data.Email, await data.Password);
if (authData) {
return authData;
}
} catch (error) {
error;
}
};
export async function LoginAction(data) {
const result = await LoginSchema.isValid(await data);
if (result === true) {
const result = await analyze(data);
if (result) {
return redirect("/");
} else {
return "failed";
}
} else {
return "failed";
}
}
This is because internally, redirect() is throwing an Error. See https://github.com/vercel/next.js/blob/canary/packages/next/src/client/components/redirect.ts#L16-L41C2
The redirect function works by throwing a specific type of error caught by NextJS. The try/catch block 'catches' the error preventing the redirect from working.
If you are using redirect
inside a try block, you can simply re-throw any redirectError in the catch block to achieve normal behaviour.
eg:
try {
doSomethingThatCouldError()
redirect("/dashboard")
} catch(error) {
// If redirect call this will re-throw it
rethrowIfRedirectError(error)
// Handle any other error as normal
console.log(error)
}
Where the reusable rethrowIfRedirectError
function is defined elsewhere as:
import { isRedirectError } from "next/dist/client/components/redirect"
export function rethrowIfRedirectError(error: unknown) {
if (isRedirectError(error)) {
throw error
}
}
The redirect()
is never supposed to be used in try/catch
blocks.
Here is a screenshot from the official docs:
screenshot of nextjs documentation about redirect()
use
return NextResponse.redirect(new URL('/home', request.url))
in next 13+ app dir server side
The error that I got was Uncaught (in promise) Error: NEXT_REDIRECT
And I'm not sure if this is a bug... Because the method needs context info that is available inside "react render time!".
So this will work if you create a reference to use it later.
import { useRouter } from 'next/navigation'
function reactFunctionComponent() {
const router = useRouter()
runWithPromise().then( () => router.push("/") )
...
}
More info
Do this instead.
import { redirect } from 'next/navigation';
export async function GET(req: Request) {
try {
// Other logic
} catch (error) {
console.log(error);
redirect('/');
}
redirect('/dashboard');
}
Internally, redirect
throws an error as mentioned here. Hence, you should not catch it nor return it.
This happened to me when I used a try...catch
statement. Rewrote my code in a way that didn't need a try...catch
statement and it now works fine. This doesn't necessarily happen to API route files only, could happen in a react component where redirect is called inside a try catch.
this is redirect
function:
function redirect(url, type) {
if (type === void 0) type = "replace";
throw getRedirectError(url, type, false);
}
this is getRedirectError()
function getRedirectError(url, type, permanent) {
if (permanent === void 0) permanent = false;
const error = new Error(REDIRECT_ERROR_CODE);
error.digest = REDIRECT_ERROR_CODE + ";" + type + ";" + url + ";" + permanent;
const requestStore = _requestasyncstorageexternal.requestAsyncStorage.getStore();
if (requestStore) {
error.mutableCookies = requestStore.mutableCookies;
}
return error;
}
Finally this is REDIRECT_ERROR_CODE
IN getRedirectError
:
const REDIRECT_ERROR_CODE = "NEXT_REDIRECT";
As you see, redirect()
throws an error and next.js watches for this error and redirects the user. so when you put redirect
inside a try/catch
block, catch
block catches this error. that is why you see the error. solution is put the redirect
outside try/catch
block
this feature is similar in sveltekit. in sveltekit we explicitly throw the redirect
. maybe next.js
should be more explicit. This can make the code more understandable to other programmers, and it can also make it easier to debug and maintain. in sveltekit
:
export const GET: RequestHandler = () => {
throw redirect(307,`URL`
}
You can use server actions with client-side, check this link in nextjs doc
export async function appRedirect(route: string) {
redirect(route)
}
// use it with async-await
await appRedirect()
As @Daniel De León said the function needs to run in a react component. A clean workaround is to return the redirect call. ex:
function redirectUser(user) {
if(user.isAdmin) {
return redirect('/dashboard');
} else {
return redirect('401');
}
}
export default async function ServerComponent(user){
await redirectUser(user);
}
Just return the response then redirect in a file that does not have a try catch block.So this could be the client or server component where the response goes
If anyone faced this issue, use isRedirectError()
function which returns true if the error is generated by redirect()
.
import { redirect } from 'next/navigation';
export async function GET(req: Request) {
try {
redirect('/dashboard');
} catch (error) {
// Do nothing if the error is generated by the redirect()
if (!isRedirectError(error)) {
console.log(error);
redirect('/');
}
}
}
For me I was calling a function with the redirect inside of it, after moving it to the main page component everything worked.
change:
const someFunction = () => {
redirect("/1234")
}
export default async function Page({
return someFunction()
})
to this:
export default async function Page({
return redirect("/1234")
})
You can also check if the error is a redirect error and "rethrow" it.
import { isRedirectError } from 'next/dist/client/components/redirect';
import { redirect } from 'next/navigation';
export async function GET(req: Request) {
try {
redirect('/dashboard');
} catch (error) {
if (isRedirectError(error)) throw error;
redirect('/');
}
}
Keep in mind though that this is an internal function and has no documentation etc. (besides JSDoc)
you can work with redirect like that:-
catch (error){
let errorMessage = "An unknown error occurred";
errorMessage = JSON.stringify(error, null, 2);
if (errorMessage.includes("NEXT_REDIRECT;push")) {
toast.success("success case");
}
else{
toast.error("Failure case");
}
If the redirect() function in Next.js is causing an error but still manages to perform the redirection, it’s likely due to how it's being used or the context of its invocation. This issue usually arises when the redirect is not being handled as expected in a server-side action or during navigation.
Now you can do permenentRedirect with Next ^15. This can be used in Server Components, Client Components, Route Handlers, and Server Actions.
import { permanentRedirect } from 'next/navigation'
async function fetchTeam(id) {
const res = await fetch('https://...')
if (!res.ok) return undefined
return res.json()
}
export default async function Profile({ params }) {
const team = await fetchTeam(params.id)
if (!team) {
permanentRedirect('/login')
}
// ...
}
https://nextjs.org/docs/app/api-reference/functions/permanentRedirect
After hours of struggling I found a solution: I added the below code to the catch block:
if (isRedirectError(error)) {
throw error;
}
本文标签: javascriptNext 134 Error NEXTREDIRECT in API routesStack Overflow
版权声明:本文标题:javascript - Next 13.4 Error: NEXT_REDIRECT in API routes - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736835422a1954872.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
appRouter
, instead. I read in the documentation that redirect returns an an NEXT_REDIRECT nextjs.org/docs/app/api-reference/functions/redirect#example, but i don't understand why and I don't understand how it is supposed to be used. – Kyle Angelo Gonzales Commented Aug 30, 2023 at 13:51then
callback. I realized this is a client component so I changed touseRouter
androuter.push
instead. – ADTC Commented Nov 29, 2023 at 15:50redirect
you cannot call without getting an error? Redirecting is just about the most basic thing you can do in a web app. And they make this complicated too? We should go back to vanilla JS it seems – Bersan Commented Feb 11, 2024 at 22:05