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.
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.
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.
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',
]);
}
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];
}
}
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;
}
}
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,
];
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.
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);
}
});
}
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 metodereport
. type-hint tersebut akan secara otomatis disuntikkan ke dalam metode oleh service container milik Laravel.
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);
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
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.