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

Next.js App Router错误边界:从服务端组件传递更多错误属性

解决Next.js App Router错误边界无法获取自定义错误属性的问题

Next.js在传递服务端组件抛出的错误到客户端错误边界时,默认仅会序列化Error的标准属性(如message、name),自定义添加的type、code等属性不会被自动保留,因此客户端无法直接访问。以下是两种可行的解决方法:

方法一:使用自定义错误类实现序列化

创建继承自Error的自定义错误类,并实现toJSON方法,让Next.js在序列化错误时包含自定义属性。

1. 定义自定义错误类(服务端使用)

// lib/errors.ts
export class CustomServerError extends Error {
  type: string;
  code: number;

  constructor(message: string, type: string, code: number) {
    super(message);
    this.name = 'CustomServerError';
    this.type = type;
    this.code = code;
    // 修复继承Error后的原型链问题
    Object.setPrototypeOf(this, CustomServerError.prototype);
  }

  // 实现toJSON方法,指定需要序列化的属性
  toJSON() {
    return {
      message: this.message,
      type: this.type,
      code: this.code,
      name: this.name,
    };
  }
}

2. 服务端组件中抛出自定义错误

// MyServerComponent.tsx
import { CustomServerError } from '@/lib/errors';

async function MyServerComponent() {
  try {
    const res = await fetch('你的接口地址');
    if (!res.ok) throw new Error('请求失败');
    // 处理接口返回数据
  } catch (e) {
    throw new CustomServerError("Something went wrong", "MyCustomType", 123);
  }

  return <div>服务端组件内容</div>;
}

export default MyServerComponent;

3. 客户端错误边界中访问自定义属性

'use client';

import { useEffect } from 'react';

interface ErrorProps {
  error: Error & { type?: string; code?: number; name?: string };
}

export default function Error({ error }: ErrorProps) {
  useEffect(() => {
    console.log(error.message); // "Something went wrong"
    console.log(error.type); // "MyCustomType"
    console.log(error.code); // 123
  }, [error]);

  return (
    <div className="error-container">
      <h2>发生错误</h2>
      <p>{error.message}</p>
      {error.type && <p>错误类型:{error.type}</p>}
      {error.code && <p>错误码:{error.code}</p>}
    </div>
  );
}

方法二:将自定义错误信息编码到message中

如果不想创建自定义类,可以将包含所有错误信息的对象序列化为JSON字符串,放到Error的message中,客户端再解析获取。

1. 服务端组件中抛出编码后的错误

// MyServerComponent.tsx
async function MyServerComponent() {
  try {
    const res = await fetch('你的接口地址');
    if (!res.ok) throw new Error('请求失败');
  } catch (e) {
    const errorPayload = JSON.stringify({
      message: "Something went wrong",
      type: "MyCustomType",
      code: 123,
    });
    throw new Error(errorPayload);
  }

  return <div>服务端组件内容</div>;
}

2. 客户端错误边界中解析message

'use client';

import { useEffect } from 'react';

interface ErrorProps {
  error: Error & { digest?: string };
}

interface CustomErrorData {
  message: string;
  type: string;
  code: number;
}

export default function Error({ error }: ErrorProps) {
  useEffect(() => {
    let errorData: CustomErrorData;
    try {
      errorData = JSON.parse(error.message) as CustomErrorData;
    } catch {
      // 解析失败时使用默认值
      errorData = {
        message: error.message,
        type: 'UnknownError',
        code: 0,
      };
    }
    console.log(errorData.message); // "Something went wrong"
    console.log(errorData.type); // "MyCustomType"
    console.log(errorData.code); // 123
  }, [error]);

  return (
    <div className="error-container">
      <h2>发生错误</h2>
      <p>{errorData.message}</p>
      <p>错误类型:{errorData.type}</p>
      <p>错误码:{errorData.code}</p>
    </div>
  );
}

内容的提问来源于stack exchange,提问作者user19448827

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 22:10:34