ملف error.js

يسمح لك ملف error بالتعامل مع الأخطاء غير المتوقعة أثناء التشغيل وعرض واجهة مستخدم احتياطية.

ملف error.js الخاص
'use client' // حدود الأخطاء يجب أن تكون مكونات عميل

import { useEffect } from 'react'

export default function Error({
  error,
  reset,
}: {
  error: Error & { digest?: string }
  reset: () => void
}) {
  useEffect(() => {
    // تسجيل الخطأ في خدمة تقارير الأخطاء
    console.error(error)
  }, [error])

  return (
    <div>
      <h2>حدث خطأ ما!</h2>
      <button
        onClick={
          // محاولة الاستعادة عن طريق إعادة عرض القطاع
          () => reset()
        }
      >
        حاول مرة أخرى
      </button>
    </div>
  )
}
'use client' // حدود الأخطاء يجب أن تكون مكونات عميل

import { useEffect } from 'react'

export default function Error({ error, reset }) {
  useEffect(() => {
    // تسجيل الخطأ في خدمة تقارير الأخطاء
    console.error(error)
  }, [error])

  return (
    <div>
      <h2>حدث خطأ ما!</h2>
      <button
        onClick={
          // محاولة الاستعادة عن طريق إعادة عرض القطاع
          () => reset()
        }
      >
        حاول مرة أخرى
      </button>
    </div>
  )
}

يقوم error.js بلف قطاع المسار وأطفاله المتداخلين في حدود خطأ React. عند حدوث خطأ داخل الحدود، يتم عرض مكون error كواجهة مستخدم احتياطية.

كيف يعمل error.js

معلومة مفيدة:

  • تسمح لك أدوات مطوري React بتبديل حدود الأخطاء لاختبار حالات الخطأ.
  • إذا كنت تريد أن تتصاعد الأخطاء إلى حد الخطأ الأب، يمكنك استخدام throw عند عرض مكون error.

المرجع

الخصائص

error

نسخة من كائن Error يتم تمريرها إلى مكون العميل error.js.

معلومة مفيدة: أثناء التطوير، يتم تسلسل كائن Error الذي يتم تمريره إلى العميل ويتضمن message للخطأ الأصلي لتسهيل التصحيح. ومع ذلك، يختلف هذا السلوك في الإنتاج لتجنب تسريب تفاصيل حساسة محتملة متضمنة في الخطأ إلى العميل.

error.message

  • الأخطاء الممررة من مكونات العميل تعرض رسالة Error الأصلية.
  • الأخطاء الممررة من مكونات الخادم تعرض رسالة عامة مع معرف. هذا لمنع تسريب التفاصيل الحساسة. يمكنك استخدام المعرف، تحت errors.digest, لمطابقة سجلات الخادم المقابلة.

error.digest

تجزئة تلقائية للخطأ الذي تم طرحه. يمكن استخدامها لمطابقة الخطأ المقابل في سجلات الخادم.

reset

يمكن أن يكون سبب الخطأ مؤقتًا في بعض الأحيان. في هذه الحالات، قد تحل المحاولة مرة أخرى المشكلة.

يمكن لمكون الخطأ استخدام دالة reset() لدفع المستخدم لمحاولة الاستعادة من الخطأ. عند التنفيذ، ستقوم الدالة بمحاولة إعادة عرض محتويات حدود الخطأ. إذا نجحت، يتم استبدال مكون الخطأ الاحتياطي بنتيجة إعادة العرض.

'use client' // حدود الأخطاء يجب أن تكون مكونات عميل

export default function Error({
  error,
  reset,
}: {
  error: Error & { digest?: string }
  reset: () => void
}) {
  return (
    <div>
      <h2>حدث خطأ ما!</h2>
      <button onClick={() => reset()}>حاول مرة أخرى</button>
    </div>
  )
}
'use client' // حدود الأخطاء يجب أن تكون مكونات عميل

export default function Error({ error, reset }) {
  return (
    <div>
      <h2>حدث خطأ ما!</h2>
      <button onClick={() => reset()}>حاول مرة أخرى</button>
    </div>
  )
}

أمثلة

خطأ عام

على الرغم من ندرته، يمكنك التعامل مع الأخطاء في تخطيط الجذر أو القالب باستخدام global-error.js, الموجود في دليل التطبيق الجذر، حتى عند استخدام التدويل. يجب أن تحدد واجهة مستخدم الخطأ العام علامات <html> و <body> الخاصة بها. يحل هذا الملف محل تخطيط الجذر أو القالب عند التنشيط.

'use client' // حدود الأخطاء يجب أن تكون مكونات عميل

export default function GlobalError({
  error,
  reset,
}: {
  error: Error & { digest?: string }
  reset: () => void
}) {
  return (
    // global-error يجب أن يتضمن علامات html و body
    <html>
      <body>
        <h2>حدث خطأ ما!</h2>
        <button onClick={() => reset()}>حاول مرة أخرى</button>
      </body>
    </html>
  )
}
'use client' // حدود الأخطاء يجب أن تكون مكونات عميل

export default function GlobalError({ error, reset }) {
  return (
    // global-error يجب أن يتضمن علامات html و body
    <html>
      <body>
        <h2>حدث خطأ ما!</h2>
        <button onClick={() => reset()}>حاول مرة أخرى</button>
      </body>
    </html>
  )
}

استعادة الأخطاء بسلاسة مع حدود خطأ مخصصة

عند فشل العرض على العميل، قد يكون من المفيد عرض آخر واجهة مستخدم معروفة من الخادم لتحسين تجربة المستخدم.

يعد GracefullyDegradingErrorBoundary مثالًا على حدود خطأ مخصصة تلتقط وتحتفظ بـ HTML الحالي قبل حدوث الخطأ. إذا حدث خطأ في العرض، فإنه يعيد عرض HTML الملتقط ويعرض شريط إشعار ثابت لإعلام المستخدم.

'use client'

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

interface ErrorBoundaryProps {
  children: ReactNode
  onError?: (error: Error, errorInfo: ErrorInfo) => void
}

interface ErrorBoundaryState {
  hasError: boolean
}

export class GracefullyDegradingErrorBoundary extends Component<
  ErrorBoundaryProps,
  ErrorBoundaryState
> {
  private contentRef: React.RefObject<HTMLDivElement>

  constructor(props: ErrorBoundaryProps) {
    super(props)
    this.state = { hasError: false }
    this.contentRef = React.createRef()
  }

  static getDerivedStateFromError(_: Error): ErrorBoundaryState {
    return { hasError: true }
  }

  componentDidCatch(error: Error, errorInfo: ErrorInfo) {
    if (this.props.onError) {
      this.props.onError(error, errorInfo)
    }
  }

  render() {
    if (this.state.hasError) {
      // عرض محتوى HTML الحالي بدون ترطيب
      return (
        <>
          <div
            ref={this.contentRef}
            suppressHydrationWarning
            dangerouslySetInnerHTML={{
              __html: this.contentRef.current?.innerHTML || '',
            }}
          />
          <div className="fixed bottom-0 left-0 right-0 bg-red-600 text-white py-4 px-6 text-center">
            <p className="font-semibold">
              حدث خطأ أثناء عرض الصفحة
            </p>
          </div>
        </>
      )
    }

    return <div ref={this.contentRef}>{this.props.children}</div>
  }
}

export default GracefullyDegradingErrorBoundary
'use client'

import React, { Component, createRef } from 'react'

class GracefullyDegradingErrorBoundary extends Component {
  constructor(props) {
    super(props)
    this.state = { hasError: false }
    this.contentRef = createRef()
  }

  static getDerivedStateFromError(_) {
    return { hasError: true }
  }

  componentDidCatch(error, errorInfo) {
    if (this.props.onError) {
      this.props.onError(error, errorInfo)
    }
  }

  render() {
    if (this.state.hasError) {
      // عرض محتوى HTML الحالي بدون ترطيب
      return (
        <>
          <div
            ref={this.contentRef}
            suppressHydrationWarning
            dangerouslySetInnerHTML={{
              __html: this.contentRef.current?.innerHTML || '',
            }}
          />
          <div className="fixed bottom-0 left-0 right-0 bg-red-600 text-white py-4 px-6 text-center">
            <p className="font-semibold">
              حدث خطأ أثناء عرض الصفحة
            </p>
          </div>
        </>
      )
    }

    return <div ref={this.contentRef}>{this.props.children}</div>
  }
}

export default GracefullyDegradingErrorBoundary

سجل الإصدارات

الإصدارالتغييرات
v15.2.0عرض global-error أيضًا في وضع التطوير.
v13.1.0إدخال global-error.
v13.0.0إدخال error.