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

Next.js 13 app目录下Error与NotFound页面无法正常显示求助

Next.js 13 App Router 自定义error.tsx未触发的问题解决

问题原因

你的error.tsx没有触发,是因为Next.js 13 App Router中,路由级别的error.tsx仅捕获以下场景的错误:

  • 服务器组件渲染时抛出的错误
  • 页面初始加载阶段(比如组件挂载时同步执行的代码)的错误
  • 路由导航过程中发生的加载错误

而你是在客户端交互(点击按钮)时异步抛出的错误,这类属于客户端运行时的交互错误,不在路由级error.tsx的默认捕获范围内。开发环境下Next.js会显示内置的错误弹窗辅助调试,生产环境下则会显示通用错误页,但都不会触发你自定义的error.tsx。

解决方案

要处理客户端交互时的错误,需要使用React Error Boundary(组件级错误捕获),结合路由级error.tsx覆盖所有场景:

步骤1:创建客户端Error Boundary组件

在app/sample目录下创建ErrorBoundary.tsx:

'use client'

import React, { Component, ErrorInfo, ReactNode } from 'react'

interface Props {
  children: ReactNode
}

interface State {
  hasError: boolean
  error: Error | null
}

class ErrorBoundary extends Component<Props, State> {
  constructor(props: Props) {
    super(props)
    this.state = { hasError: false, error: null }
  }

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

  componentDidCatch(error: Error, errorInfo: ErrorInfo) {
    console.error('Error Boundary caught error:', error, errorInfo)
  }

  resetError = () => {
    this.setState({ hasError: false, error: null })
  }

  render() {
    if (this.state.hasError) {
      return (
        <div className="space-y-4">
          <h2 className="text-lg font-bold">Error</h2>
          <p className="text-sm">{this.state.error?.message}</p>
          <div>
            <button onClick={this.resetError}>Try Again</button>
          </div>
        </div>
      )
    }

    return this.props.children
  }
}

export default ErrorBoundary

步骤2:用Error Boundary包裹Sample组件

修改app/sample/page.tsx,将组件用Error Boundary包裹:

'use client'

import ErrorBoundary from './ErrorBoundary'

export default function Sample() {
  const error = () => {
    throw new Error(new Date().toISOString())
  }

  return (
    <ErrorBoundary>
      <main className="flex flex-col items-center justify-between p-24">
        Sample
        <button onClick={error}>Throw Error</button>
      </main>
    </ErrorBoundary>
  )
}

补充说明

  • 路由级error.tsx依然保留,用于处理服务器组件、初始加载、路由导航的错误。
  • 开发环境下,你可以通过关闭Next.js的错误弹窗(在弹窗设置里勾选"Disable Error Overlay")来测试Error Boundary的效果,生产环境下会直接显示自定义错误界面。
  • 如果需要全局统一处理客户端错误,可以在根目录app下创建全局的Error Boundary,包裹整个应用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 09:27:39