آموزش مدیریت خطا و لاگ در لاراول (error handling) | Exception در لاراول

دسته بندی: لاراول
زمان مطالعه: 7 دقیقه
۲۱ مرداد ۱۳۹۹

گاهی اوقات ممکن است در حین کدنویسی دچار مشکلاتی شوید، یکی از این مشکلات این است که شما نمی‌توانید رفتار کاربر را پیش بینی کنید و بنابراین کاربر ممکن است مشکلاتی را برای برنامه و اپلیکیشن شما پیش بیاورد و در صورتی که برای حل این مشکلات راه حل درستی نداشته باشید، اپلیکیشن شما به راحتی آسیب‌های بزرگی می‌بیند. استفاده از 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

جمع‌بندی :

همان‌طور که در ابتدا گفتیم شما نمی‌توانید رفتار کاربر را پیش بینی کنید و بنابراین کاربر ممکن است مشکلاتی را برای برنامه و اپلیکیشن شما پیش بیاورد که جبران برخی از این مشکلات و مدیریت خطاها بسیار زمان‌بر و دشوار است. پس بهتر است که در همان ابتدا راه حل درستی برای این مشکلات در نظر بگیریم. به همین علت است که مدیریت خطا در لاراول نقش بسیار مهمی در امنیت اپلیکیشن یا سایت ما دارد.

اگر به یادگیری بیشتر لاراول علاقه دارید می‌توانید در دوره آموزشی لاراول کاربردی (بسته پروژه محور) شرکت کنید، این دوره شامل ۱۲ پروژه کاربردی و پر استفاده در دنیای واقعی است، که تمامی پروژه‌ها به صورت کامل برنامه‌ نویسی خواهند شد، تا دانشجو بتواند با روند ایجاد و تکمیل پروژه به صورت کامل آشنا شود.

چه امتیازی به این مقاله می دید؟
نویسنده علی مجیدی
Backend Developer | PHP & Laravel Developer

نظرات کاربران

اولین دیدگاه این پست رو تو بنویس !

ارسال دیدگاه
خوشحال میشیم دیدگاه و یا تجربیات خودتون رو با ما در میون بذارید :