Error & Exception

Hierarki Throwable (Error vs Exception), try/catch/finally, exception kustom, multi-catch, dan penanganan error yang benar.

Part 13 dari 22 ± 40 menit Gratis

Mengapa penanganan error penting?

Di dunia nyata, hal buruk pasti terjadi: file hilang, database mati, input ngawur, koneksi putus. Program yang baik tidak "meledak" di depan pengguna, melainkan menangani kegagalan dengan anggun dan mencatatnya untuk developer.

Throwable: Error vs Exception

Throwable
├── Error                  → kesalahan fatal bahasa (PHP 7+)
│   ├── TypeError, ValueError, ArithmeticError → DivisionByZeroError
│   └── ArgumentCountError, UnhandledMatchError, ...
└── Exception              → kegagalan yang dapat diantisipasi
    ├── RuntimeException   (gagal saat berjalan: file, jaringan, DB)
    ├── LogicException     (kesalahan logika/programmer)
    │   └── InvalidArgumentException, DomainException, ...
    └── JsonException, PDOException, ...

Sejak PHP 7 kebanyakan "fatal error" menjadi objek Error yang bisa ditangkap. Di PHP 8, banyak warning lama naik pangkat menjadi Error/TypeError/ValueError sehingga bug tidak diam-diam.

try / catch / finally

function bagi(int $a, int $b): float
{
    if ($b === 0) {
        throw new InvalidArgumentException('Pembagi tidak boleh nol');
    }
    return $a / $b;
}

try {
    echo bagi(10, 0);
} catch (InvalidArgumentException $e) {
    echo 'Input salah: ' . $e->getMessage();
} catch (RuntimeException | LogicException $e) {   // multi-catch
    echo 'Masalah lain';
} finally {
    echo "\nSelalu dijalankan (bersih-bersih)";
}
  • Urutkan catch dari yang paling spesifik ke umum.
  • finally selalu jalan — tempat menutup file/koneksi.
  • Sejak PHP 8 variabel boleh dihilangkan: catch (RuntimeException).

Exception kustom

class StokTidakCukupException extends RuntimeException
{
    public function __construct(
        public readonly string $produk,
        public readonly int $diminta,
        public readonly int $tersedia,
    ) {
        parent::__construct("Stok {$produk} tidak cukup: diminta {$diminta}, tersedia {$tersedia}");
    }
}

throw new StokTidakCukupException('Mouse', 5, 2);

Exception kustom membuat penangan bisa memilah penyebab dengan tepat, dan membawa data tambahan (produk, jumlah) alih-alih mengurai teks pesan.

Exception berantai (previous)

try {
    $pdo->query($sql);
} catch (PDOException $e) {
    throw new RuntimeException('Gagal menyimpan pesanan', 0, $e);   // $e disimpan sebagai previous
}

$e->getPrevious(), getFile(), getLine(), dan getTraceAsString() membantu menelusuri akar masalah.

Aturan emas

  • Jangan telan exception diam-diam (catch {} kosong). Minimal catat log.
  • Jangan bocorkan detail teknis ke pengguna di produksi (display_errors=Off, log_errors=On). Tampilkan pesan ramah, simpan detailnya di log.
  • Tangkap di tempat yang bisa berbuat sesuatu (coba lagi, pesan ke pengguna); sisanya biarkan naik ke penangan global (set_exception_handler / error handler framework).
  • Gunakan exception untuk keadaan luar biasa, bukan alur normal.

Mengubah warning menjadi exception

set_error_handler(function (int $no, string $msg, string $file, int $line) {
    throw new ErrorException($msg, 0, $no, $file, $line);
});

Framework modern melakukan ini untukmu agar semua masalah punya alur penanganan yang seragam.

Praktikkan langsung, gratis

Tulis dan jalankan kode langsung di browser, dapatkan penilaian otomatis. Daftar gratis kapan saja untuk menyimpan progres dan meraih sertifikat.

Coba latihan sekarang, tanpa daftar
Bagikan: WhatsApp Facebook LinkedIn X