في كثير من الأحيان لا يهتم المطورين بدرجة كافية بمعالجة الأخطاء، فغالبا ما نرى نصوص لارافيل الإفتراضية مثل 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
مقالات قصيرة وعملية وهادفة جزاك الله خيرا معلومات ثرية جدا
زائر
مقالات قصيرة وعملية هادفة احسنت