اذهب إلى المحتوى

السؤال

نشر

لدي الكود التالي:

components/SomeErroringComponent.vue:

<template>
  <div>This will trigger an error in two seconds.</div>
</template>

<script setup>
onMounted(() => {
  throw new Error('bob')
})
</script>

pages/index.vue:

<template>
  <div>
    <NuxtErrorBoundary @error="someErrorLogger">
      <SomeErroringComponent />
      <template #error="ctx"> An error happened. </template>
    </NuxtErrorBoundary>
  </div>
</template>

<script setup>
function someErrorLogger(err) {
  console.log('got an error', err);
}
</script>

ألاحظ أنني عندما أقوم بالدخول مباشرة للصفحة عبر مربع البحث, فإن هذا المكون (NuxtErrorBoundary) لا يقوم بعمله, بل تظهر صفحة الخطأ 500

لكن عندما أقوم بالدخول إليها عبر مكون NuxtLink فهي تعمل

أظن هذا يحدث بسبب أن الدخول إلى الصفحة مباشرة عبر مربع البحث يجعل Nuxt  يقوم بعملية الـ rendering من السيرفر وبالتالي يشغل الكود throw new error("this is error") من هناك, بالتالي السيرفر يرسل كنتيجة صفحة 500

لكن إذا دخلت إلى الصفحة من المكون NuxtLink فإن Nuxt يقوم بعملية الـ rendering من المتصفح, ومنه تشغيل كود throw new error("this is error") وبالتالي مكون NuxtErrorBoundary يعمل

لكن سؤالي هو لو كان لدي صفحة منتجات على سبيل المثال وأردت استخدام NuxtErrorBoundary لإظهار عنصر معين عند حدوث Error في عرض المنتجات فكيف أقوم بهذا باعتبار أن الـ Error سيحدث في السيرفر   

Recommended Posts

  • 0
نشر

NuxtErrorBoundary الغرض منه التعامل مع أخطاء العرض rendering errors أو الأخطاء التي تحدث بعد بدء العرض أو في دورات حياة معينة كـ onMounted في المتصفح، وذكرت أنّ المشكلة تحدث عند جلب البيانات من الخادم وذلك يمنع عرض الصفحة.

الأفضل التعامل مع أخطاء جلب البيانات التي تحدث على الخادم أو العميل من خلال استخدام state التي توفرها أدوات جلب البيانات في Nuxt مثل useFetch أو useAsyncData، لمنع ظهور صفحة الخطأ 500.

<template>
  <div>
    <NuxtErrorBoundary @error="logProductError">
      <template #default>
        <div v-if="pending" class="loading">
          جاري التحميل...
        </div>
        <div v-else-if="products.length" class="products">
          <div v-for="product in products" :key="product.id">
            {{ product.name }}
          </div>
        </div>
        <div v-else class="no-products">
          لا توجد منتجات
        </div>
      </template>

      <template #error="{ error }">
        <div class="error-container">
          <p>عذراً، حدث خطأ في تحميل المنتجات</p>
          <button @click="handleRetry">
            إعادة المحاولة
          </button>
        </div>
      </template>
    </NuxtErrorBoundary>
  </div>
</template>

<script setup>
import { ref } from 'vue';
import { useFetch, clearNuxtError } from '#app';

const { data: products, pending, error, refresh } = useFetch('/api/products', {
  default: () => [],
  lazy: true, 
  server: true, 
  watch: true, 
});

function logProductError(err) {
  console.error('NuxtErrorBoundary caught an error:', err);
}

watch(error, (newError) => {
  if (newError) {
    console.error('Error fetching products:', newError);
  }
});

async function handleRetry() {
  try {
    clearNuxtError();
    await refresh();
  } catch (e) {
    console.error('Retry failed:', e);
  }
}

onUnmounted(() => {
  
});
</script>

ولاحظ تم التعامل مع  الحالات المختلفة:

<div v-if="pending">جاري التحميل...</div>
<div v-else-if="error">حدث خطأ</div>
<div v-else-if="products.length">عرض المنتجات</div>
<div v-else>لا توجد منتجات</div>

 

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...