Tutorial Laravel #29: Error Handling dan Logging di Laravel

1. Error Handling di Laravel

Laravel menangani semua exception secara terpusat melalui exception handler. Ketika terjadi error, Laravel bisa menampilkan halaman error yang informatif (mode development) atau halaman yang ramah user (mode production).

2. Konfigurasi Debug Mode

# .env
APP_DEBUG=true   # development: tampilkan detail error
APP_DEBUG=false  # production: sembunyikan detail error

Di mode production (APP_DEBUG=false), Laravel menampilkan halaman error sederhana tanpa stack trace. Kamu bisa kustomisasi halaman error ini.

3. Kustomisasi Halaman Error

# Buat view untuk halaman error
# resources/views/errors/404.blade.php
# resources/views/errors/403.blade.php
# resources/views/errors/500.blade.php
<!-- resources/views/errors/404.blade.php -->
@extends('layouts.app')

@section('content')
<div class="text-center py-5">
    <h1 class="display-1">404</h1>
    <h2>Halaman Tidak Ditemukan</h2>
    <p class="text-muted">Halaman yang kamu cari tidak ada atau sudah dihapus.</p>
    <a href="{{ url('/') }}" class="btn btn-primary">Kembali ke Beranda</a>
</div>
@endsection

4. Throw Exception Manual

// Throw HTTP exception
abort(404, 'Artikel tidak ditemukan');
abort(403, 'Kamu tidak punya akses ke halaman ini');
abort(500, 'Terjadi kesalahan server');

// Throw hanya jika kondisi terpenuhi
abort_if(!auth()->check(), 401);
abort_unless(auth()->user()->isAdmin(), 403);

// Custom exception
throw new Exception('Terjadi kesalahan');
throw new InvalidArgumentException('Argumen tidak valid');
throw new RuntimeException('Runtime error');

5. Custom Exception Class

php artisan make:exception InsufficientStockException
php artisan make:exception PaymentFailedException
<?php
// app/Exceptions/InsufficientStockException.php
namespace AppExceptions;

use Exception;

class InsufficientStockException extends Exception
{
    public function __construct(
        private string $produk,
        private int $stokTersedia,
        private int $stokDiminta
    ) {
        parent::__construct(
            "Stok $produk tidak mencukupi. Tersedia: $stokTersedia, diminta: $stokDiminta"
        );
    }

    // Otomatis render response saat exception ini di-throw
    public function render($request)
    {
        if ($request->expectsJson()) {
            return response()->json([
                'error'   => 'Insufficient Stock',
                'message' => $this->getMessage(),
            ], 422);
        }

        return redirect()->back()->with('error', $this->getMessage());
    }
}

6. Logging di Laravel

Laravel menggunakan Monolog untuk logging dengan berbagai channel (file, Slack, daily rotation, dsb). Konfigurasi di config/logging.php.

use IlluminateSupportFacadesLog;

// Berbagai level log
Log::debug('Debug info');
Log::info('Informasi biasa');
Log::notice('Perhatian');
Log::warning('Peringatan');
Log::error('Error terjadi');
Log::critical('Masalah kritis');
Log::alert('Butuh perhatian segera');
Log::emergency('Sistem tidak bisa berjalan');

// Log dengan context
Log::info('User login', [
    'user_id' => auth()->id(),
    'ip'      => request()->ip(),
    'waktu'   => now()->toDateTimeString(),
]);

Log::error('Pembayaran gagal', [
    'order_id' => $order->id,
    'amount'   => $order->total,
    'error'    => $e->getMessage(),
]);

7. Channel Logging Kustom

// config/logging.php - tambahkan channel
'channels' => [
    'daily' => [
        'driver' => 'daily',
        'path'   => storage_path('logs/laravel.log'),
        'days'   => 14,   // simpan 14 hari
    ],

    'payment' => [
        'driver' => 'single',
        'path'   => storage_path('logs/payment.log'),
        'level'  => 'debug',
    ],
],

// Gunakan channel spesifik
Log::channel('payment')->info('Pembayaran berhasil', ['order_id' => 123]);
Log::channel('daily')->error('Error harian');

8. Ringkasan

  • Set APP_DEBUG=false di production untuk menyembunyikan detail error
  • Kustomisasi halaman error di resources/views/errors/
  • Buat custom exception class untuk error yang spesifik di aplikasi
  • Gunakan Log::error(), Log::info(), dsb untuk mencatat aktivitas penting

Tutorial berikutnya membahas mini project CRUD Laravel - menggabungkan semua yang sudah dipelajari!


ariq fadhil

Im Ariq Tech, a Top Rated Fullstack Developer with 5+ years of experience, delivering high-quality solutions across 50+ projects.