下一页 13.4 错误:API 路由中的 NEXT_REDIRECT

Aid*_*hsy 32 next.js

我的 /app/api/auth/route.ts 文件:

import { redirect } from 'next/navigation';

export async function GET(req: Request) {
  try {
    redirect('/dashboard');
  } catch (error) {
    console.log(error);
    redirect('/');
  }
}
Run Code Online (Sandbox Code Playgroud)

我意识到当我在 try catch 中进行重定向时,我收到错误:

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'
}
Run Code Online (Sandbox Code Playgroud)

当我摆脱 try catch 时,一切正常:

export async function GET(req: Request) {
  redirect('/dashboard')
}
Run Code Online (Sandbox Code Playgroud)

这按预期工作。我需要尝试并捕获,因为这是一个身份验证路由,并且我需要一些错误处理,因为请求可能会失败,我省略了身份验证功能,因为我意识到这只是在简单的尝试和捕获上发生的。

或者,如果 Next 13 在 /api 路由中有另一种错误处理方式,请告诉我。

小智 31

目前,我发现的解决方法是不使用:

import { redirect } from 'next/navigation';
Run Code Online (Sandbox Code Playgroud)

但要改为使用:

import { useRouter } from 'next/navigation'
const router = useRouter()
router.push("/")
Run Code Online (Sandbox Code Playgroud)

  • 请注意,这些是不同的方法,每种方法都有其优缺点。“useRouter”作为前端实用程序运行,而“redirect”适用于服务器端。在这些方法之间切换可能会导致您的页面更多地依赖客户端组件和 JavaScript 来实现完整功能。在我看来,遵循@Rugile Venskute 的建议似乎是目前最合适的解决方案。 (4认同)

小智 13

修复它很容易。try-catch目前,下一个重定向块中存在错误。但你不需要改变任何东西。您只需要将try-catch块转移到不同的功能即可。我可以给你一个我的代码的例子:

"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";
  }
}
Run Code Online (Sandbox Code Playgroud)


小智 7

这是因为在内部,redirect() 抛出了一个错误。请参阅https://github.com/vercel/next.js/blob/canary/packages/next/src/client/components/redirect.ts#L16-L41C2

  • 请注意,您链接的片段中的行号将来可能会发生变化。您可能想要锚定到特定的 git 标签而不是金丝雀分支。 (2认同)
  • 哇,多么可怕的事情啊。很好的发现,有点埋在这里的文档中(https://nextjs.org/docs/app/api-reference/functions/redirect#example),但我永远不会在那里看,因为它的行为如此奇怪,但它流媒体所需的技巧。 (2认同)