Skip to content

Latest commit

 

History

History
293 lines (220 loc) · 13.6 KB

errors.md

File metadata and controls

293 lines (220 loc) · 13.6 KB

Penanganan Eror

Pendahuluan

Saat Anda memulai proyek Laravel yang baru, penanganan eror dan exception telah terkonfigurasi. Di kelas App\Exceptions\Handler, semua exception yang dilemparkan oleh aplikasi Anda telah dicatat dan diteruskan ke pengguna. Jadi, Kita akan membahas lebih dalam mengenai kelas ini di sepanjang halaman dokumentasi ini.

Konfigurasi

Opsi debug pada file konfigurasi config/app.php menentukan berapa banyak informasi tentang eror yang akan ditampilkan kepada pengguna. Secara default, opsi ini sudah diatur untuk mengikuti nilai variabel environment APP_DEBUG, yang disimpan di file .env Anda.

Selama pengembangan pada tahap lokal, Anda harus menetapkan variabel environment APP_DEBUG menjadi true. Pada environment production Anda, nilai pada variabel APP_DEBUG harus selalu false. Jika nilai diatur ke true dalam production, Anda membuat risiko mengekspos nilai konfigurasi yang sensitif kepada pengguna aplikasi Anda.

Penanganan Exeception

Melaporkan Exception

Semua exception ditangani oleh kelas App\Exceptions\Handler. Kelas ini berisi metode register tempat Anda dapat mendaftarkan pelaporan exception khusus dan menampilkan callback. Kami akan memeriksa masing-masing konsep ini secara rinci. Laporan exception digunakan untuk mencatat exception atau mengirimkannya ke layanan eksternal, seperti Flare, Bugsnag, atau Sentry. Secara default, exception akan dicatat berdasarkan konfigurasi pencatatan log Anda. Namun, Anda boleh mencatat exception saat mengerjakan proyek Anda.

Misalnya, jika Anda ingin melaporkan jenis exception yang berbeda dengan menggunakan cara yang berbeda, Anda dapat menggunakan metode reportable untuk mendaftarkan closure yang harus dijalankan saat exception jenis tertentu perlu dilaporkan. Laravel akan menyimpulkan jenis exception apa yang dilaporkan oleh closure dengan memeriksa tipe-petunjuk dari closure:

use App\Exceptions\InvalidOrderException;

/**
 * Mendaftarkan callback untuk penanganan exception pada aplikasi.
 *
 * @return void
 */
public function register()
{
    $this->reportable(function (InvalidOrderException $e) {
        //
    });
}

Saat Anda mendaftarkan callback untuk pelaporan exception yang kustom menggunakan metode reportable, Laravel selalu mencatat exception menggunakan konfigurasi pencatatan log yang default. Jika Anda ingin berhenti menyebarkan exception ke tumpukan logging default, Anda dapat menggunakan metode stop saat mendefinisikan callback untuk pelaporan, atau mengembalikan false dari callback tersebut:

$this->reportable(function (InvalidOrderException $e) {
    //
})->stop();

$this->reportable(function (InvalidOrderException $e) {
    return false;
});

Catatan
Untuk menyesuaikan pelaporan exception pada exception tertentu, Anda juga dapat menggunakan reportable exception.

Konteks Log Global

Jika tersedia, Laravel akan secara otomatis menambahkan ID pengguna saat ini ke setiap pesan log exception sebagai data kontekstual. Anda dapat menentukan data kontekstual global Anda sendiri dengan mengganti metode context dari kelas App\Exceptions\Handler pada aplikasi Anda. Informasi ini akan disertakan dalam setiap pesan log exception yang ditulis oleh aplikasi Anda:

/**
 * Dapatkan variabel konteks default untuk pencatatan.
 *
 * @return array
 */
protected function context()
{
    return array_merge(parent::context(), [
        'foo' => 'bar',
    ]);
}

Konteks Log Exception

Meskipun menambahkan konteks ke setiap pesan log dapat membantu, terkadang beberapa exception dapat memiliki konteks unik yang ingin Anda sertakan dalam log. Dengan mendefinisikan metode context pada pada salah satu exception kustom milik Anda, Anda dapat menentukan data apa saja yang relevan untuk exception tersebut dan akan ditambahkan ke entri log exception:

<?php

namespace App\Exceptions;

use Exception;

class InvalidOrderException extends Exception
{
    // ...

    /**
     * Mengambil informasi konteks exception.
     *
     * @return array
     */
    public function context()
    {
        return ['order_id' => $this->orderId];
    }
}

report Pembantu

Terkadang Anda mungkin perlu melaporkan exception tetapi terus menangani permintaan saat ini. Fungsi helper report memungkinkan Anda melaporkan exception dengan cepat melalui pengendali exception tanpa menampilkan halaman eror ke pengguna:

public function isValid($value)
{
    try {
        // Validasi nilainya...
    } catch (Throwable $e) {
        report($e);

        return false;
    }
}

Tingkatan Log Exception

Ketika pesan ditulis ke log milik aplikasi Anda, pesan ditulis pada tingkatan log tertentu, yang menunjukkan tingkat keseriusan atau pentingnya pesan yang sedang dicatat dalam log.

Seperti yang disebutkan di atas, bahkan saat mendaftarkan callback pelaporan exception yang kustom menggunakan metode reportable, Laravel akan tetap mencatat exception menggunakan konfigurasi logging default untuk aplikasi. Namun, karena level log terkadang dapat memengaruhi kanal tempat pesan dicatat, Anda mungkin ingin mengonfigurasi level log di mana exception tertentu akan dicatat.

Untuk melakukannya, Anda dapat menentukan array dengan tipe exception dan tingkat log yang terkait di dalam properti $levels dari pengendali exception aplikasi Anda :

use PDOException;
use Psr\Log\LogLevel;

/**
 * Daftar jenis exception dengan tingkat log kustom yang sesuai.
 *
 * @var array<class-string<\Throwable>, \Psr\Log\LogLevel::*>
 */
protected $levels = [
    PDOException::class => LogLevel::CRITICAL,
];

Mengabaikan Exception Berdasarkan Jenis

Saat membuat aplikasi Anda, akan ada beberapa jenis exception yang ingin Anda abaikan dan tidak pernah laporkan. Pengendali exception aplikasi Anda berisi properti $dontReport yang diinisialisasi ke array kosong. Setiap kelas yang Anda tambahkan ke properti ini tidak akan dilaporkan. Namun, mereka mungkin masih memiliki logika rendering yang kustom :

use App\Exceptions\InvalidOrderException;

/**
 * Daftar tipe exception yang tidak dilaporkan.
 *
 * @var array<int, class-string<\Throwable>>
 */
protected $dontReport = [
    InvalidOrderException::class,
];

Catatan
Di belakang layar, Laravel sudah mengabaikan beberapa jenis eror untuk Anda, seperti exception yang dihasilkan dari eror 404 HTTP "not found" atau 419 respons HTTP yang dihasilkan oleh token CSRF yang tidak valid.

Menampilkan Exception

Secara default, penanganan exception Laravel akan mengonversi exception menjadi respons HTTP untuk Anda. Namun, Anda bebas mendaftarkan closure pe-render-an khusus untuk exception dari jenis tertentu. Anda dapat melakukannya melalui metode renderable pada penanganan exception Anda.

Closure yang diteruskan ke metode renderable harus mengembalikan instance Illuminate\Http\Response, yang dapat dihasilkan menggunakan bantuan response. Laravel akan menyimpulkan jenis exception apa yang dibuat oleh closure dengan memeriksa type-hint dari closure :

use App\Exceptions\InvalidOrderException;

/**
 * Daftarkan callback penanganan exception untuk aplikasi.
 *
 * @return void
 */
public function register()
{
    $this->renderable(function (InvalidOrderException $e, $request) {
        return response()->view('errors.invalid-order', [], 500);
    });
}

Kamu juga dapat menggunakan metode renderable untuk mengganti perilaku rendering untuk exception Laravel atau Symfony bawaan seperti NotFoundHttpException. Jika closure yang diberikan ke metode renderable tidak mengembalikan nilai, pe-render-an exception yang default milik Laravel akan digunakan:

use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

/**
 * Mendaftarkan callback penanganan exception untuk aplikasi.
 *
 * @return void
 */
public function register()
{
    $this->renderable(function (NotFoundHttpException $e, $request) {
        if ($request->is('api/*')) {
            return response()->json([
                'message' => 'Record not found.'
            ], 404);
        }
    });
}

Exception yang Dapat Dilaporkan & Ditampilkan

Alih-alih memeriksa jenis exception dalam metode register milik penangan exception, Anda dapat mendefinisikan metode report dan render langsung pada exception kustom Anda. Ketika metode ini didefinisikan, mereka akan dipanggil secara otomatis oleh framework :

<?php

namespace App\Exceptions;

use Exception;

class InvalidOrderException extends Exception
{
    /**
     * Laporkan exception.
     *
     * @return bool|null
     */
    public function report()
    {
        //
    }

    /**
     * Render exception menjadi respons HTTP.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function render($request)
    {
        return response(/* ... */);
    }
}

Jika exception Anda melakukan extend dari exception yang sudah bisa di-render, seperti pada bawaan Laravel atau exception Symfony, Anda dapat mengembalikan false dari metode render exception untuk menampilkan respons HTTP yang default untuk exception:

/**
 * Render exception menjadi respons HTTP.
 *
 * @param  \Illuminate\Http\Request  $request
 * @return \Illuminate\Http\Response
 */
public function render($request)
{
    // Tentukan apakah exception membutuhkan rendering khusus...

    return false;
}

Jika exception Anda berisi logika pelaporan kustom yang hanya diperlukan ketika kondisi tertentu terpenuhi, Anda mungkin perlu menginstruksikan Laravel untuk jarang melaporkan exception tersebut menggunakan konfigurasi penanganan exception default. Untuk mencapai hal tersebut, Anda dapat mengembalikan nilai false dari metode report exception:

/**
 * Laporkan exception.
 *
 * @return bool|null
 */
public function report()
{
    // Tentukan apakah exception membutuhkan pelaporan khusus...

    return false;
}

Catatan
Kamu dapat melakukan type-hint dependensi pada metode report. type-hint tersebut akan secara otomatis disuntikkan ke dalam metode oleh service container milik Laravel.

HTTP Exception

Beberapa exception mendeskripsikan kode eror HTTP dari server. Misalnya, ini mungkin eror "page not found" error (404), "unauthorized error" (401), atau bahkan eror 500 yang dihasilkan pengembang. Untuk menghasilkan respon seperti itu, Anda dapat menggunakan bantuan abort:

abort(404);

Halaman Eror Kustom HTTP

Laravel mempermudah Anda untuk menampilkan halaman eror kustom untuk berbagai kode status HTTP yang berbeda. Misalnya, jika Anda ingin menyesuaikan halaman eror untuk kode status HTTP 404, Anda dapat membuat template tampilan pada resources/views/errors/404.blade.php. Tampilan ini akan ditampilkan pada semua eror 404 yang dihasilkan oleh aplikasi Anda. Tampilan dalam direktori ini harus diberi nama yang sama dengan kode status HTTP yang dikembalikan. Instance dari Symfony\Component\HttpKernel\Exception\HttpException yang dipicu oleh fungsi abort akan diteruskan ke tampilan sebagai variabel $exception :

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

Kamu dapat mempublikasikan template halaman eror default milik Laravel menggunakan perintah Artisan vendor:publish. Setelah file template dipublikasikan, Anda dapat mengubahnya sesuai dengan keinginan Anda:

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

Halaman Eror Fallback HTTP

Anda juga dapat menentukan halaman eror "fallback" untuk sekumpulan kode status pada HTTP tertentu. Halaman ini akan ditampilkan jika tidak ada halaman yang sesuai untuk kode status HTTP yang ditentukan. Untuk melakukannya, Anda dapat membuat file template 4xx.blade.php dan template 5xx.blade.php di direktori resources/views/errors aplikasi Anda.