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

Next.js 13.5.2 App Router中抛出错误无法触发error.js页面

解决Next.js 13.5.2 App Router客户端组件错误不触发error.jsx的问题

原因分析

Next.js App Router中的error.jsx默认仅处理服务器组件或页面级的服务器端渲染错误,客户端组件运行时抛出的错误不会自动触发该文件,只会在控制台报错——因为客户端错误需要通过React的错误边界机制来捕获处理。

解决方案:使用React错误边界包裹客户端组件

步骤1:创建错误边界组件

在项目中新建客户端组件components/ErrorBoundary.jsx,用来捕获子组件的错误并处理跳转或错误展示:

"use client";

import React from "react";
import { useRouter } from "next/navigation";

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false, error: null };
  }

  static getDerivedStateFromError(error) {
    return { hasError: true, error };
  }

  componentDidCatch(error, errorInfo) {
    console.error("组件错误详情:", error, errorInfo);
  }

  render() {
    const { hasError, error } = this.state;
    const router = useRouter();

    if (hasError) {
      // 针对403权限错误跳转到自定义错误页面,或直接渲染错误内容
      React.useEffect(() => {
        // 跳转到全局错误页面(需提前创建app/error/page.jsx)
        router.push("/error");
      }, [router]);

      // 跳转前显示临时错误提示
      return (
        <div className="flex flex-col items-center justify-center h-64">
          <h3 className="text-red-500 text-xl">操作失败</h3>
          <p className="mt-2">{error?.message || "未知错误"}</p>
        </div>
      );
    }

    return this.props.children;
  }
}

export default ErrorBoundary;

步骤2:在页面组件中用错误边界包裹UserTable

修改app/(site)/users/page.jsx,将UserTable用错误边界组件包裹:

"use client";

import React from "react";
import UserTable from "@/components/partials/tables/UserTable";
import ErrorBoundary from "@/components/ErrorBoundary";

const Users = () => {
   return (
     <div className="space-y-5">
         <ErrorBoundary>
             <UserTable />
         </ErrorBoundary>
     </div>
   );
 };
export default Users;

替代方案:状态提升到页面组件处理

如果不想使用类组件的错误边界,也可以通过状态提升将错误传递到页面组件,直接处理错误展示:

  1. 修改UserTable.jsx,将错误通过回调传递给父组件:
"use client";

import React, { useState, useEffect } from "react";
import axios from "axios";

const UserTable = ({ onError }) => {
  const [data, setData] = useState([]);

  const fetchUsers = async () => {
    try {
      const res = await axios.get("/api/users");
      if (res.status === 403) {
        throw new Error("权限不足,无法访问用户列表");
      }
      setData(res.data);
    } catch (err) {
      onError(err);
    }
  };

  useEffect(() => {
    fetchUsers();
  }, []);

  return (
    <table className="w-full border-collapse">
      {/* 表格渲染逻辑 */}
    </table>
  );
};

export default UserTable;
  1. 在users/page.jsx中接收错误并处理:
"use client";

import React, { useState } from "react";
import UserTable from "@/components/partials/tables/UserTable";

const Users = () => {
  const [error, setError] = useState(null);

  if (error) {
    // 直接渲染错误内容
    return (
      <div className="flex flex-col items-center justify-center h-64">
        <h3 className="text-red-500 text-xl">权限不足</h3>
        <p className="mt-2">{error.message}</p>
      </div>
    );
  }

  return (
    <div className="space-y-5">
      <UserTable onError={setError} />
    </div>
  );
};

export default Users;

关键注意点

  • error.jsx核心作用是处理服务器端渲染错误或服务器组件的错误,客户端组件的运行时错误必须用React错误边界处理。
  • 若需要统一的全局错误页面,可创建app/error/page.jsx,再通过useRouter跳转至该页面。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 13:32:40