لارافيل, Blade / 2024-03-04

التعامل مع الأخطاء exceptions بطريقة صحيحة في laravel

التعامل مع الأخطاء exceptions بطريقة صحيحة في laravel

2024-03-04 وقت القراءه : 3 دقائق

في كثير من الأحيان لا يهتم المطورين بدرجة كافية بمعالجة الأخطاء، فغالبا ما نرى نصوص لارافيل الإفتراضية مثل 500 , 404 والتي لا تفيد الزائر بأي معلومة، في هذه المقالة سوف نتعرف على كيفية التعامل مع الأخطاء بطريقة أنيقة وتقدم معلومات مناسبة للزائر.
بداية ماذا لو كنا نريد إرجاع قسم / مقال ... حسب id، العنوان ...

In eloquent
public function index($id){
   $cat = Cat::where('id',$id)->first();
   return view('admin.cats.indexcats',compact('cat'));
}

in blade
<div>{{ $cat->title }}</div>


إذا كان هذا الـ id موجود سوف يتم إرجاع البيانات، أما إذا كان الخطأ غير موجود فسيتم إرجاع الخطئ التالي

ErrorException
Trying to get property 'title' of non-object (View: /Library/WebServer/Documents/test/resources/views/admin/cats/indexcats.blade.php)
http://www.test.test/cat/100

الخطأ هنا جاء من blade لأن الـ object $cat-title فارغ، ولم نقم بالتحقق إذا تم إرجاع بيانات من eloquent أم لا، ودور المطور أن يتم إرجاع رسالة واضحة للمستخدم.

الحلول :

واحدة من أهم الإمور التي يجب القيام بها بل وتعتبر security issue هو تغيير قيمة app_debug من true إلى false في ملف .env

APP_DEBUG=false


بعد تغيير قيمة app_debugg إلى false، إذا كان الـ id غير موجود فسوف يتم إرجاع صفحة

500 Server Error

الحل الثاني هو إستخدام firstOrFail عوضا عن إستخدام first، فعند إستخدامها إذا كان id غير موجود فسيتم إرجاع صفحة 404 | Not Found.

رسالة 404 تعتبر مفهومه أكثر من 500، لكن هذا غير كافي فيجب أن يفهم زوار الموقع ما الذي يحصل.

الحلول لخطأ 404 حتى تظهر رسالة مفهومة للزوار
إنشاء مجلد باسم errors بداخل مجلد resources/views وبداخل مجلد errors ننشئ ملف 404.blade.php ونكتب بها الرسالة التي نريدها.
الحل الأخر هو إستخدام try,catch في eloquent

try {
   $cat = Cat::where('id',$id)->first();
}catch (\Exception $exception){
   return view('admin.cats.datanotfound')
}


هنا سوف يتم إظهر صفحة datanotfound للمستخدم إذا لم يتم إيجاد الـ id.

كما نلاحظ أنه تم تحديد نوع $exception بـ \Exception ، فهو يرجع أخطأ عامة وليس أخطاء محددة.

لتوضيح أنواع Exception لنفرض أننا في جملة eloquent نستخدم العلاقات وهذه العلاقة غير موجوده

try {
   $cat = Cat::where('id',$id)->with('projects')->first();
}catch (\Exception $exception){
   return view('admin.cats.datanotfound');
}


في المثال أعلاه لا يوجد function بداخل CatModel باسم projects بمعنى أنه لا يوجد علاقه بين جدول cat و project، هنا سوف يتم توجيه المستخدم الى صفحة datanotfound أيضا دون تحديد المشكله.
لمعرفة الرسالة الحقيقية للخطأ نستخدم $exception->getMessage

try {
   $cat = Cat::where('id',$id)->with('projects')->first();
}catch (\Exception $exception){
   dd($exception->getMessage());
return view('admin.cats.datanotfound');
}


هنا سوف يظهر لنا الخطأ التالي

"Call to undefined relationship [projects] on model [App\Models\Cat]."


بمعنى أنه لا يوجد علاقه بين الجدولين.

ولمعرفة الكلاس المسؤول عن إرجاع هذا الخطأ نستخدم get_class($exception)

try {
   $cat = Cat::where('id',$id)->with('projects')->first();
}catch (\Exception $exception){
   dd(get_class($exception));
return view('admin.cats.datanotfound');
} 


فيظهر لنا إسم الكلاس

"Illuminate\Database\Eloquent\RelationNotFoundException"


ولإستخدام الكلاس

try {
   $cat = Cat::where('id',$id)->with('projects')->first();
}catch (\Illuminate\Database\Eloquent\RelationNotFoundException $exception){
   return view('admin.cats.relationsNotFoud');
}


هنا سوف يتم تحويل المستخدم إلى صفحة relationsNotFound.

كما يمكن إستخدام أكثر من exception في نفس الجملة

use Illuminate\Database\Eloquent\RelationNotFoundException;
use Illuminate\Database\Eloquent\ModelNotFoundException;

try {
    $cat = Cat::where('id',$id)->with('projects')->first();
}catch (\Exception $exception){
    return view('admin.cats.datanotfound');
}catch (ModelNotFoundException $exception){
    return view('admin.cats.modelNotFound');
}catch (RelationNotFoundException $exception){
    return view('admin.cats.relationsNotFoud');
}
return view('admin.cats.indexcats',compact('cat'));


واحدة من أفضل الأمثلة التي يمكن مشاهدة لإستخدام exceptions هي صفحة stripe error handiling
stripe error handiling


التعليقات
زائر
منذ سنتين

مقالات قصيرة وعملية هادفة احسنت

moemen
منذ سنتين

مقالات قصيرة وعملية وهادفة جزاك الله خيرا معلومات ثرية جدا

إضافة تعليق
Loading...