گاهی اوقات ممکن است در حین کدنویسی دچار مشکلاتی شوید، یکی از این مشکلات این است که شما نمیتوانید رفتار کاربر را پیش بینی کنید و بنابراین کاربر ممکن است مشکلاتی را برای برنامه و اپلیکیشن شما پیش بیاورد و در صورتی که برای حل این مشکلات راه حل درستی نداشته باشید، اپلیکیشن شما به راحتی آسیبهای بزرگی میبیند. استفاده از Exceptionها در لاراول باعث میشود تا بتوانید رفتارهای غیر معمولی کاربران اپلیکیشن خود را کنترل کنید و برای آنها راه حلهای مناسبی داشته باشید. در صورتی که از این Exceptionها در لاراول استفاده نکنید ممکن است خطاهایی ناخواسته و ناگهانی در اپلیکیشن شما رخ دهد که باعث میشود Debug کردن و مدیریت خطاهای اپلیکیشن برای شما بسیار سخت شود. در این مقاله به آموزش مدیریت خطا در لاراول میپردازیم.
هنگامی که یک پروژهی جدید Laravel را شروع میکنید، مدیریت خطا و Exceptionها در لاراول از قبل برای شما Config شده است. کلاس App\Exceptions\Handler همان جایی است که تمام Exceptionهای برنامهی شما log میشود و سپس برای کاربر نمایش داده میشود. در ادامه بهصورت دقیقتر به این موضوع میپردازیم.
قسمتی بهنام debug در فایل config/app.php تعیین میکند که در واقع چه مقدار اطلاعاتی را در مورد یک خطا میخواهید به کاربر نمایش دهید. بهطور پیشفرض، این Option همان مقداری را دارد که مقدار متغیر APP_DEBUG در فایل env. دارا میباشد.
برای local development یا توسعه محلی، باید مقدار متغیر APP_DEBUG را true و برای production environment یا همان محیط اصلی که در دید کاربران قرار دارد، این مقدار را false بگذارید. اگر این مقدار در production environment برابر با true باشد، کاربران میتوانند به اطلاعات حساس و مهمی از برنامهی شما دسترسی پیدا کنند.
تمام Exceptionها در لاراول توسط کلاس App\Exceptions\Handler که شامل دو متد report و render میباشد، مدیریت میشوند. در ادامه به جزییات این دو متد، یعنی متد report و render میپردازیم.
از متد report برای ثبت logهای Exceptionها یا ارسال آنها به یک سرویس خارجی مانند Flare ,Bugnag یا Sentry استفاده میشود. بهطور پیشفرض، متد Exception ,reportها را به کلاس پایه (کلاسی که Exceptionها در آن log میشوند) منتقل میکند. با این حال، شما میتوانید Exceptionها را هر جای دیگری که میخواهید log کنید.
بهطور مثال، اگر بخواهید انواع مختلفی از Exceptionها را با روشهای مختلفی report کنید، میتوانید به شکل زیر از instanceof استفاده کنید.
/**
* Report or log an exception.
*
* This is a great spot to send exceptions to Flare, Sentry, Bugsnag, etc.
*
* @param \Throwable $exception
* @return void
*/
public function report(Throwable $exception)
{
if ($exception instanceof CustomException) {
//
}
parent::report($exception);
}
/**
* Get the default context variables for logging.
*
* @return array
*/
protected function context()
{
return array_merge(parent::context(), [
'foo' => 'bar',
]);
}
گاهی اوقات میخواهید پس از اینکه یک Exception را report کردید، به مدیریت Requestها ادامه دهید و از آنها خارج نشوید. تابع report helper به شما این امکان را میدهد که یک Exception را با استفاده از متد report از handler، بدون این که یک صفحهی ارور render شود، به سرعت report کنید.
public function isValid($value)
{
try {
// Validate the value...
} catch (Throwable $e) {
report($e);
return false;
}
}
Property بهنام dontReport$ شامل type هایی از Exception هاست که نمیخواهیم از آنها log گرفته شود.
/**
* A list of the exception types that should not be reported.
*
* @var array
*/
protected $dontReport = [
\Illuminate\Auth\AuthenticationException::class,
\Illuminate\Auth\Access\AuthorizationException::class,
\Symfony\Component\HttpKernel\Exception\HttpException::class,
\Illuminate\Database\Eloquent\ModelNotFoundException::class,
\Illuminate\Validation\ValidationException::class,
];
متد render وظیفهی تبدیل یک Exception داده شده به HTTP Response که باید به مرورگر ارسال شود را دارد. بهطور پیشفرض، متد Exception ,renderها را به کلاس پایه (کلاسی که response را برای شما ایجاد میکند) منتقل میکند.
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Throwable $exception
* @return \Illuminate\Http\Response
*/
public function render($request, Throwable $exception)
{
if ($exception instanceof CustomException) {
return response()->view('errors.custom', [], 500);
}
return parent::render($request, $exception);
}
شما میتوانید علاوه بر بررسی نوع Exceptionها در متد report یا render توسط Exception Handler ها، این متدها را مستقیماً برای Exception دلخواه خود تعریف کنید. لازم به ذکر است که این متدها زمانی که وجود داشته باشند، بهطور خودکار توسط فریم ورک فراخوانی میشوند.
<?php
namespace App\Exceptions;
use Exception;
class RenderException extends Exception
{
/**
* Report the exception.
*
* @return void
*/
public function report()
{
//
}
/**
* Render the exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function render($request)
{
return response(...);
}
}
بعضی از Exceptionها کدهای HTTP Error را از سرور توصیف میکنند. به عنوان مثال، خطاهای “page not found” یا error 404، خطای unauthorized یا error 401 را در نظر بگیرید.
به منظور ایجاد چنین Response هایی از هر جای برنامهی خود، میتوانید از abort helper استفاده کنید.
abort(404);
abort helper بلافاصله یک Exception که توسط Exception Helper ارائه (render) میشود را نمایان میکند. شما میتوانید بهصورت کاملا اختیاری، متن Response را به دلخواه وارد کنید.
abort(403, 'Unauthorized action.');
Laravel نمایش صفحات سفارشی error را برای کدهای مختلف HTTP بسیار آسان کرده است. بهطور مثال، اگر میخواهید صفحهی error 404 را سفارشیسازی کنید، میتوانید یک resources/views/errors/404.blade.php ایجاد کنید. این فایل روی تمام ارورهای 404 ایجاد شده توسط برنامهی شما اعمال میشود. Viewهای داخل این Directory باید برای مطابقت با کدهای HTTP، حتما نامگذاری شوند. در نهایت instance یا همان نمونهی HttpException که توسط تابع abort مطرح شده است به عنوان یک متغیر exception$ به View ارسال میشود.
<h2>{{ $exception->getMessage() }}</h2>
شما میتوانید templateهای صفحهی ارور Laravel را با استفاده از vendor:publish منتشر کنید. پس از منتشر شدن template ها، میتوانید آنها را بهصورت دلخواه خود تنظیم کنید.
php artisan vendor:publish --tag=laravel-errors
جمعبندی :
همانطور که در ابتدا گفتیم شما نمیتوانید رفتار کاربر را پیش بینی کنید و بنابراین کاربر ممکن است مشکلاتی را برای برنامه و اپلیکیشن شما پیش بیاورد که جبران برخی از این مشکلات و مدیریت خطاها بسیار زمانبر و دشوار است. پس بهتر است که در همان ابتدا راه حل درستی برای این مشکلات در نظر بگیریم. به همین علت است که مدیریت خطا در لاراول نقش بسیار مهمی در امنیت اپلیکیشن یا سایت ما دارد.
اگر به یادگیری بیشتر لاراول علاقه دارید میتوانید در دوره آموزش لاراول کاربردی (بسته پروژه محور) شرکت کنید، این دوره شامل ۱۲ پروژه کاربردی و پر استفاده در دنیای واقعی است، که تمامی پروژهها به صورت کامل برنامه نویسی خواهند شد، تا دانشجو بتواند با روند ایجاد و تکمیل پروژه به صورت کامل آشنا شود.