گاهی اوقات ممکن است در حین کدنویسی دچار مشکلاتی شوید، یکی از این مشکلات این است که شما نمیتوانید رفتار کاربر را پیش بینی کنید و بنابراین کاربر ممکن است مشکلاتی را برای برنامه و اپلیکیشن شما پیش بیاورد و در صورتی که برای حل این مشکلات راه حل درستی نداشته باشید، اپلیکیشن شما به راحتی آسیبهای بزرگی میبیند. استفاده از Exceptionها در لاراول باعث میشود تا بتوانید رفتارهای غیر معمولی کاربران اپلیکیشن خود را کنترل کنید و برای آنها راه حلهای مناسبی داشته باشید. در صورتی که از این Exceptionها در لاراول استفاده نکنید ممکن است خطاهایی ناخواسته و ناگهانی در اپلیکیشن شما رخ دهد که باعث میشود Debug کردن و مدیریت خطاهای اپلیکیشن برای شما بسیار سخت شود. در این مقاله به آموزش مدیریت خطا در لاراول میپردازیم.
مقدمه ای بر Exception ها
هنگامی که یک پروژه ی جدید 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 ها
تمام Exceptionها در لاراول توسط کلاس App\Exceptions\Handler که شامل دو متد report و render میباشد، مدیریت میشوند. در ادامه به جزییات این دو متد، یعنی متد report و render میپردازیم.
متد Report
از متد 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);
}
متن log برای Exception ها
Laravel به طور خودکار برای هر کاربر، شناسه یا همان id کاربر را به متن logهای Exception هایی که کاربر با آنها مواجه میشود اضافه میکند. شما میتوانید برای لاگ در لاراول این متن را همان گونه که میخواهید در متد context از کلاس App\Exceptions\Handler بازنویسی یا Override کنید.
/**
* Get the default context variables for logging.
*
* @return array
*/
protected function context()
{
return array_merge(parent::context(), [
'foo' => 'bar',
]);
}
Report Helper
گاهی اوقات میخواهید پس از اینکه یک 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;
}
}
نادیده گرفتن برخی از Exception ها
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
متد 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);
}
قابل Report یا Render بودن یک 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(...);
}
}
HTTP Exception ها
بعضی از 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.');
صفحه ی HTTP Error سفارشی
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
جمع بندی :
همان طور که در ابتدا گفتیم شما نمیتوانید رفتار کاربر را پیش بینی کنید و بنابراین کاربر ممکن است مشکلاتی را برای برنامه و اپلیکیشن شما پیش بیاورد که جبران برخی از این مشکلات و مدیریت خطاها بسیار زمان بر و دشوار است. پس بهتر است که در همان ابتدا راه حل درستی برای این مشکلات در نظر بگیریم. به همین علت است که مدیریت خطا در لاراول نقش بسیار مهمی در امنیت اپلیکیشن یا سایت ما دارد.
اگر به یادگیری بیشتر لاراول علاقه دارید میتوانید در دوره آموزش لاراول کاربردی (بسته پروژه محور) شرکت کنید، این دوره شامل ۱۲ پروژه کاربردی و پر استفاده در دنیای واقعی است، که تمامی پروژهها به صورت کامل برنامه نویسی خواهند شد، تا دانشجو بتواند با روند ایجاد و تکمیل پروژه به صورت کامل آشنا شود.