PHP Menengah

10. Penanganan Error 1

PHP: Jenis dan Penanganan Error [1/2]

Pendahuluan

Kemunculan error saat pengembangan suatu aplikasi adalah sesuatu yang tidak-bisa-tidak. Ia pasti terjadi. Bahkan ketika aplikasi/web yang kita kerjakan sudah rilis pun, error tetap menjadi makanan sehari-hari kita. Ia pasti dan harus muncul.

Error apa pun yang muncul, harus ditangani dengan tepat. Baik ketika aplikasi masih dalam pengembangan, lebih-leibh lagi ketika aplikasi telah dilempar ke publik.

Penangan standar terhadap suatu error adalah:

  1. Menampilkan pesan permohonan maaf kepada pengguna karena terjadi error
  2. Menyimpan atau menulis log error agar bisa kita perbaiki dengan mudah
  3. Mengirim pemberitahuan secara real-time ke pemrogram agar error bisa ditangani saat itu juga

Jenis-Jenis Error Pada PHP

Di dalam PHP, terdapat beberapa jenis dan tingkatan level error. Sebagiannya error yang sangat fatal sehingga program tidak bisa dilanjutkan, sebagiannya lagi hanya bersifat peringatan sehinggax` program masih bisa dilanjutkan.

Berikut ini beberapa diantara level dan jenis error yang harus diketahui pada PHP:

KonstantaDeskripsiLevel
E_ERRORError fatal yang terjadi saat run-time program. Eksekusi skrip akan langsung dihentikan1
E_WARNINGError non-fatal yang terjadi saat run-time. Skrip (setelah terjadi error) tetap dieksekusi2
E_PARSEError yang terjadi pada saat compile-time. Error parse ini terjadi ketika interpreter PHP mendeteksi adanya sintaks error.4
E_NOTICEPemberitahuan kemungkinan error pada saat run-time. Suatu baris program bisa jadi ia normal-normal saja, tapi bisa jadi error pada keadaan tertentu.8
E_USER_ERRORError fatal yang terjadi saat run-time program. Sama dengan E_ERROR hanya saja error jenis ini dipicu oleh pemrogram dengan memanggil fungsi trigger_error()256
E_USER_WARNINGError non-fatal yang terjadi saat run-time. Sama dengan E_WARNING hanya saja error jenis ini dipicu oleh pemrogram dengan memanggil fungsi trigger_error()512
E_USER_NOTICEPemberitahuan kemungkinan error pada saat run-time. Sama dengan E_NOTICE hanya saja error jenis ini dipicu oleh pemrogram dengan memanggil fungsi trigger_error()1024

Untuk level error yang lebih lengkap, silakan merujuk ke dokumentasi manual PHP.

Cara Penanganan Error

Setiap kali menulis kode program, kita harus selalu membuat pemeriksaan pada setiap kemungkinan terjadinya error. Sehingga jika memang terjadi error pada tempat tersebut, kita bisa memberikan aksi yang tepat.

Di antara cara penanganan error yang bisa kita lakukan adalah:

  1. Menggunakan fungsi die()
  2. Memusatkan penanganan error pada satu fungsi khusus
  3. Menggunakan exception

Menggunakan Fungsi die()

Misalkan kita akan membuka dan membaca suatu file dengan PHP, kita harus memeriksa terlebih dahulu apakah file tersebut tersedia atau tidak. Jika ternyata file tidak tersedia, kita bisa menghentikan run-time program dengan memanggil fungsi die().

Perhatikan kode program berikut:

<?php

$namaFile = "/web/documents/histori.txt";

if (!file_exists($namaFile)) {
  die("File tidak ditemukan");
} else {
  $file = fopen($namaFile, "r");
  echo "File berhasil dibaca.";
}

// lanjutkan kode jika file berhasil dibaca

Pemusatan Error Handling

Selain cara menggunakan if else seperti di atas, kita bisa melakukan cara yang lebih umum yaitu dengan memusatkan error handling dalam satu fungsi saja.

Sehingga setiap kali ada error dari setiap level, fungsi tersebut akan otomatis dipanggil. Setelah itu, kita bisa memutuskan apa yang akan kita lakukan dengan error yang terjadi tersebut.

Langkah-langkahnya adalah:

1. Membuat fungsi

Langkah yang pertama adalah membuat fungsi khusus untuk menangani error.

Fungsi tersebut harus memiliki 5 buah parameter:

  • $errLevel: berisi konstanta tipa error level
  • $errMessage: berisi label/pesan dari error
  • $errFile: berisi file di mana error terjadi
  • $errLine: berisi baris di mana error terjadi

Sebelum itu, jangan lupa kita non aktifkan semua pesan error. Karena beberapa pengaturan bawaan PHP di sistem operasi tertentu pesan error akan ditampilkan secara default. Sehingga kita harus mengaturnya mandiri dengan mengubah nilai di file php.ini mau pun dengan memanggil fungsi error_reporting().

<?php

# sembunyikan semua pesan error bawaan PHP
error_reporting(0);

/**
 * Fungsi untuk menangai error.
 * 
 * Fungsi ini wajib memiliki 4 paramter dan nama parameter bisa bebas.
 */
function tanganiError ($level, $message, $file, $line) {
  echo "<div style='padding: 2rem; background: rgba(200, 0, 0, 0.5); color: white'>";
  echo    "<b>Terjadi Error</b>";
  echo    "<p>[{$level}] {$message} - {$file}:{$line}</p>";
  echo "</div>";
}

2. Mengatur fungsi tersebut sebagai error handler

Kita telah membuat fungsi tanganiError(). Fungsi tersebut menerima 5 buah parameter.

Yang harus kita lakukan selanjutnya adalah mengatur fungsi tersebut sebagai error handler. Sehingga jika terjadi error apa pun pada saat run-time, fungsi tersebut akan dieksekusi.

Untuk mengatur error handler kita bisa memanggil fungsi bawaan PHP bernama set_error_handler.

<?php

set_error_handler('tanganiError');

3. Testing error

Kita coba memicu sebuah error dengan memanggil variabel yang tidak pernah kita definisikan sebelumnya.

<?php

# variabel $tes tidak ada
echo $tes;

Setelah program dijalankan, berikut ini output yang saya dapatkan:

Menggunakan Shutdown Function

Cara di atas memang sekilas berhasil, akan tetapi cara tersebut tidak berfungsi untuk semua jenis error.

Kita telah berusaha memanggil suatu variabel yang belum pernah kita definisikan sebelumnya.

Akan tetapi jika kita memanggil sebuah fungsi yang tidak pernah didefinisikan, level error yang dihasilkan adalah: E_ERROR. Dan level ini tidak didukung oleh set_error_handler. Sehingga fungsi tanganiError() tidak pernah dipanggil.

Coba kode program berikut:

<?php

# fungsi selamatPagi() tidak pernah kita definisikan
selamatPagi();

Dan setelah dieksekusi, fungsi tanganiError() yang telah kita set sebagai error handler ternyata memang tidak dianggil. Ini tangkapan layar dari apa yang saya dapat:

Lalu bagaimana caranya?

Agar kita bisa menangani error level E_ERROR, kita punya pilihan untuk menggunakan shutdown function.

Shutdown function adalah fungsi yang akan dipanggil sesaat ketika program PHP akan selesai. Entah terjadi error E_ERROR atau tidak.

Mendaftarkan fungsi anonim sebagai shutdown function

Berikut ini contoh untuk mendaftarkan sebuah fungsi anonim sebagai shutdown function. Fungsi ini akan mengambil error terakhir yang terjadi pada saat run-time, lalu akan memanggil fungsi tanganiError() jika memang ada error.

<?php

register_shutdown_function(function () {
    if (error_get_last()) {
        # ambil error terakhir
        $error = (object) error_get_last();

        tanganiError(
            $error->type, $error->message, $error->file, $error->line
        );
    }
});

Coba panggil lagi fungsi selamatPagi():

<?php

# fungsi selamatPagi() tidak pernah didefinisikan
selamatPagi();

Hasilnya:

Sembunyikan Semua Output Ketika Terjadi Error

Kita telah berhasil menangani error E_ERROR menggunakan shutdown function. Akan tetapi, jika kita perhatikan, output apa pun sebelum terjadi error akan tetap ditampilkan.

Perhatikan kode program berikut:

<?php

echo "<h1>Selamat Datang</h1>";
echo "<h2>Ini adalah halaman utama</h2>";

# fungsi selamatPagi() tidak pernah didefinisikan
selamatPagi();

echo "<p>Semoga bermanfaat</p>";

Kode program di atas akan menghasilkan output sebagai berikut:

Menggunakan fungsi ob_start() dan ob_end_flush()

Fungsi ob_start() akan menyimpan semua output dalam internal buffer PHP. Sehingga output tidak langsung ditampilkan ke dalam browser melainkan akan ditampilkan terakhir-terakhir menjelang program PHP selesai dieksekusi.

Tambahkan fungsi ob_start() sebelum output pertama, dan panggil fungsi ob_end_flush() setelah output terakhir.

<?php

ob_start();
echo "<h1>Selamat Datang</h1>";
echo "<h2>Ini adalah halaman utama</h2>";

# fungsi selamatPagi() tidak pernah didefinisikan
selamatPagi();

ob_end_flush();

Panggil fungsi ob_end_clean() untuk menghapus output

Setelah itu, kita bisa memanggil fungsi ob_end_clean() untuk menghapus semua output yang terisimpan dalam internal buffer. Dalam artian output tersebut tidak jadi ditampilkan.

Fungsi tersebut kita panggil pada saat teradi error:

<?php

register_shutdown_function(function () {
    if (error_get_last()) {
        # ambil error terakhir
        $error = (object) error_get_last();
        
        # hapus semua output sebelum terjadi error
        ob_end_clean();

        tanganiError(
            $error->type, $error->message, $error->file, $error->line
        );
    }
});

Ketika program kita jalankan lagi, kita akan dapati semua output sebelum terjadi error, ia tidak ditampilkan.

Menangani Sintaks Error

Kita sejauh ini telah berhasil menangani berbagai macam jenis error bahkan sampai fatal error sekalipun.

Akan tetapi, kode program yang telah kita buat di atas tidak bisa menangani sintaks error. Misalkan kita menghapus satu tanda titik koma (;), program kita akan error dan fungsi penanganan error yang sudah kita buat tidak akan pernah dipanggil meskipun kita sudah membuat shutdown function.

Lalu, bagaimana cara mengatasi error E_PARSE alias sintaks error?

Caranya sama saja, yang kita perlu tahu adalah:

  1. Error handle harus tidak ada error
  2. File utama yang dieksekusi tidak boleh ada error
  3. Error sintaks harus berada di file sekunder (selain file utama)

Langsung saja kita praktikkan, kita akan pecah kode program yang telah kita buat sebelumnya menjadi 3 file sebagai berikut:

├── src/
|   ├── file-yang-error.php
|   ├── index.php
|   └── penanganan-error.php
├── ...

Penjelasan:

  1. File index.php adalah file utama, yang artinya file tersebut adalah file yang kita request (melalui browser)
  2. Semua error handling kita sendirikan di dalam file penanganan-error.php
  3. File yang berisi sintaks error (atau error apa pun lainnya) kita letakkan pada file-yang-error.php

Berikut adalah kode program file index.php:

<?php

require_once 'penanganan-error.php'; /* <-- shutdown fungsi berada di sini */

ob_start();
require 'file-yang-error.php'; /* <-- file yang berisi error */
ob_end_flush();

Nah ketika di file-yang-error.php terdapat error secara sintaks, PHP masih tetap bisa menjalankan file utama yaitu index.php dan shutdown function yang telah kita definisikan di file penanganan-error.php bisa dijalankan.

<?php

echo "<h1>Selamat Datang</h1>";
echo "<h2>Ini adalah halaman utama</h2>";

# fungsi selamatPagi() tidak pernah didefinisikan
selamatPagi() # dia juga tidak ada titik koma

echo "Halo pemirsah!";

Kode Program Lengkap

Untuk kode program lengkap pada pertemuan ini bisa anda akses di sini.

Kesimpulan

Di dalam PHP terdapat berbagai jenis level error. Mulai dari yang fatal hingga menghentikan program. Ada yang tidak sampai level tersebut sehingga program masih memungkinkan untuk dilanjutkan.

Untuk menangani error pada PHP, terdapat berbagai macam pendekatan. Dalam pertemuan di atas kita telah menggunakan setidaknya 2 buah pendekatan inti:

  • Menggunakan set_error_handler()
  • Dan Menggunakan register_shutdown_function()

Tidak hanya itu, kita juga telah berhasil menyembunyikan semua output yang di-echo sebelum terjadinya error memanfaatkan fungsi ob_start() dan ob_end_clean().

Pembahasan Selanjutnya

Pada pembahasan selanjutnya, insyaallah kita masih akan membahas tentang penanganan error. Akan tetapi menggunakan cara yang lebih modern yaitu Exception. Cara ini adalah fitur baru di PHP 5, dan pendekatan ini juga mirip dengan bahasa pemrograman modern lainnya.