مفاهیم پایه ای لاراول 7 - Error Handling

مدیریت خطا

  • مقدمه
  • پیکربندی
  • مدیریت استثنائات
    • متد Report 
    • متد Render
    • استثنائات Reportable و Renderable 
  • استثنائاتHTTP 
    • سفارشی کردن HTTP Error Pages

مقدمه

هنگامی که شما یک پروژه جدید لاراول را شروع می کنید ، از قبل مدیریت خطا و استثنائات برای شما پیکربندی شده است. کلاس App\Exceptions\Handler جایی است که تمام استثنائات برنامه شما ثبت می شود و سپس به کاربر ارسال می شود. ما در این آموزش بیشتر به این مفاهیم می پردازیم.

پیکربندی

گزینه debug در فایل کانفیگ config/app.php مشخص میکند که چه مقدار اطلاعات در مورد یک خطا به کاربر نمایش داده شود. به صورت پیش فرض، این گزینه برای مقدار متغیر محیطی APP_DEBUG مشخص شده که در فایل .env ذخیره شده است.

برای پیاده سازی لوکال، باید مقدار متغیرAPP_DEBUG را true کنید.در بخش production این مقدار همیشه باید false باشد. اگر در بخش تولید یا production، این مقدارtrue ست شود، ریسک قرار گرفتن مقادیر حساس پیکربندی برای کاربران end user برنامه وجود دارد. 

مدیریت استثنائات

متد Report

تمام exception ها با کلاس App\Exceptions\Handler مدیریت می شوند. این کلاس شامل دو متد report و render است. ما هردو متد را با جزئیات بررسی خواهیم کرد. متد report برای ثبت لاگ exception ها یا ارسال آنها به یک سرویس خارجی مانند FlareBugsnag یا Sentry استفاده شده است.  به طور پیش فرض ، متد report استثنائات را به کلاسی که exception در آن ثبت شده منتقل می کند. با این حال ، شما می توانید موارد exception را به دلخواه خود وارد کنید.

به عنوان مثال ، اگر نیاز دارید انواع مختلفی از exception را به روش های مختلف report کنید ، می توانید از عملگر مقایسه PHP 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);
    }

Global Log Context

 Laravel به طور خودکار user's ID کاربر فعلی را به هر exception's log message به عنوان داده های متنی اضافه می کند. شما می توانید داده های متنی global خود را با override متد context کلاس App\Exceptions\Handler تعریف کنید. این اطلاعات در هر exception's log message که توسط برنامه شما نوشته شده است درج می شود:

/**
     * Get the default context variables for logging.
     *
     * @return array
     */
    protected function context()
    {
        return array_merge(parent::context(), [
            'foo' =‌>‌ 'bar',
        ]);
    }

report Helper

گاهی اوقات نیاز به report یک exception دارید ولی باید به هندل کردن ریکوئست جاری ادامه دهید. تابع report helper به شما اجازه می دهد که بتوانید با استفاده از متد exception handler report بدون ارسال صفحه ارور خیلی سریع report بگیرید.

public function isValid($value)
    {
        try {
            // Validate the value...
        } catch (Throwable $e) {
            report($e);
    
            return false;
        }
    }

Ignoring Exceptions By Type

ویژگی $dontReport از exception handler شامل آرایه ای از انواع exception است که لاگ نمی شود. به عنوان مثال ، exception های ناشی از ارورهای 404 ، و همچنین چندین نوع ارور دیگر ، در log file ها نوشته نشده است. در صورت لزوم می توانید انواع exception های دیگری را به این آرایه اضافه کنید:

/**
     * 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 به base class منتقل می شود که پاسخی برای شما ایجاد می کند. با این حال ، شما می توانید نوع exception را بررسی کنید یا custom 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);
    }

استثنائات Reportable و Renderable 

بجای بررسی نوع exception در متدهای report و render ، شما می توانید متدهای render و report را مستقیماً روی custom 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 ها، کدهای خطای HTTP از سرور را توصیف می کنند. به عنوان مثال: ارور (404) پیغام "page not found" ، ارور (401) پیغام "unauthorized error" ، و یا ارور (500) که خطای developer است. به این ترتیب برای تولید چنین response هایی از هر جایی در برنامه می توانید از abort helper استفاده کنید:

abort(404);

abort helper یک exception که توسط exception handler ارائه می شود را مطرح می کند.در صورت تمایل میتوانید response text زیر را ارائه دهید:

abort(403, 'Unauthorized action.');

سفارشی کردن HTTP Error Pages

لاراول نمایش صفحات خطای سفارشی را برای کدهای وضعیت مختلف HTTP آسان می کند. به عنوان مثال ، اگر می خواهید error page را برای کدهای وضعیت 404 HTTP سفارشی کنید ، یک resources/views/errors/404.blade.php ایجاد کنید.این فایل روی تمام خطاهای 404 ایجاد شده توسط برنامه شما ارائه می شود.view های موجود در این دایرکتوری باید با کد وضعیت HTTP که با آن مطابقت دارند match باشد. مورد HttpException که توسط تابع abort ایحاد شده است به عنوان یک متغیر $exception به view ارسال می شود:

‌<‌h2‌>‌{{ $exception-‌>‌getMessage() }}‌<‌/h2‌>‌

شما می توانید error page templates های لاراول را با دستور vendor:publish Artisan پابلیش کنید و سپس آنها را به دلخواه خود customize کنید:

php artisan vendor:publish --tag=laravel-errors