You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js生产构建中,如何从Server Action抛出错误以触发客户端组件的catch块?

Next.js生产构建中,如何从Server Action抛出错误以触发客户端组件的catch块?

我完全懂你的困扰——开发环境下Server Action抛出的自定义错误能被客户端组件的catch块正常捕获解析,但一到生产构建,Next.js就把错误信息给模糊处理了,导致你原本的错误结构直接变成了通用提示,客户端的JSON.parse直接报错。

其实Next.js这么做是出于安全考虑,生产环境下默认会隐藏错误详情,防止泄露服务器端的敏感信息。不过官方目前并没有提供直接“禁用这个错误抑制功能”的开关,但咱们可以通过正确的方式传递自定义错误,让客户端能正常拿到咱们想要的错误内容。

给你两个可行的解决方案:

方案一:用Next.js的unstable_throwUserError传递自定义错误

这个API虽然标了“unstable”,但实际项目里已经被广泛使用,后续很大概率会转正。它专门用来在Server Action中抛出用户可见的错误,Next.js不会在生产环境修改它的内容。

  1. 首先在你的Server Action文件里导入这个函数:
// path/to/action.ts
"use server";

import AuthApi from "@/src/api/auth/auth-api";
import { unstable_throwUserError } from 'next/server'; // 新增导入

export const submitForm = async (payload: any) => {
  try {
    const response: any = await AuthApi.login(payload);

    return {
      status: response.data.code,
      data: response,
    };
  } catch (error: any) {
    const errorObj = {
      status: error.data.code,
      data: error,
    };

    // 替换原来的throw语句
    unstable_throwUserError(JSON.stringify(errorObj));
  }
};
  1. 客户端组件里捕获错误后解析:
// path/to/login.tsx
"use client";

import { submitForm } from "path/to/login/action";

const Login = async () => { // 注意这里要加async
    try {
        const payload = { /* 你的表单数据 */ };
        const data = await submitForm(payload);
        // 处理成功逻辑
    } catch (error) {
        // 这里的error.message就是咱们传入的JSON字符串
        console.error(JSON.parse(error.message));
    }

    return <>Login form</>;
};

export default Login;

方案二:返回错误状态而非抛出错误(更稳妥)

如果不想依赖不稳定的API,咱们可以调整逻辑,不抛出错误,而是返回一个包含成功/失败状态的对象,客户端根据状态来处理:

  1. 修改Server Action:
// path/to/action.ts
"use server";

import AuthApi from "@/src/api/auth/auth-api";

export const submitForm = async (payload: any) => {
  try {
    const response: any = await AuthApi.login(payload);

    return {
      success: true,
      status: response.data.code,
      data: response,
    };
  } catch (error: any) {
    return {
      success: false,
      status: error.data.code,
      data: error,
    };
  }
};
  1. 客户端组件处理逻辑:
// path/to/login.tsx
"use client";

import { submitForm } from "path/to/login/action";

const Login = async () => {
    const payload = { /* 你的表单数据 */ };
    const result = await submitForm(payload);
    
    if (!result.success) {
        // 处理错误逻辑
        console.error(result.data);
    } else {
        // 处理成功逻辑
        console.log(result.data);
    }

    return <>Login form</>;
};

export default Login;

这种方式不需要依赖try-catch,完全不受Next.js生产环境错误抑制的影响,稳定性更高。

备注:内容来源于stack exchange,提问作者Mayeenul Islam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 16:40:29