Error Handling di PHP

Pelajari cara menangani error dengan baik di PHP untuk membuat aplikasi yang robust dan user-friendly. Error handling yang tepat sangat penting untuk pengalaman pengguna yang baik.

Jenis-Jenis Error di PHP

PHP memiliki beberapa jenis error yang perlu kita pahami untuk menanganinya dengan baik.

Level Error PHP

Level Konstanta Deskripsi
Fatal Error E_ERROR Error fatal yang menghentikan eksekusi script
Warning E_WARNING Error non-fatal, script tetap berjalan
Notice E_NOTICE Peringatan untuk kemungkinan error
Parse Error E_PARSE Error sintaks dalam kode
Strict E_STRICT Saran untuk kompatibilitas kode

Contoh Error Umum

<?php
// Notice: Undefined variable
echo $undefinedVar; 

// Warning: Division by zero
echo 10 / 0;

// Fatal Error: Call to undefined function
undefinedFunction();

// Parse Error: Syntax error
// echo "Hello World"  // Missing semicolon
?>

Mengonfigurasi Error Reporting

<?php
// Menampilkan semua error
error_reporting(E_ALL);
ini_set('display_errors', 1);

// Hanya menampilkan error fatal
error_reporting(E_ERROR | E_PARSE);

// Menyembunyikan semua error
error_reporting(0);
ini_set('display_errors', 0);

// Untuk development
error_reporting(E_ALL);
ini_set('display_errors', 1);
ini_set('log_errors', 1);
?>
Penting: Jangan menampilkan error di production. Gunakan logging untuk mencatat error dan tampilkan pesan yang user-friendly.

Try-Catch Exception Handling

Exception handling memungkinkan kita menangani error dengan graceful tanpa menghentikan aplikasi secara tiba-tiba.

Dasar Try-Catch

<?php
try {
    // Kode yang mungkin menghasilkan exception
    $result = 10 / 0;
    echo $result;
} catch (DivisionByZeroError $e) {
    echo "Error: " . $e->getMessage();
} catch (Exception $e) {
    echo "Exception umum: " . $e->getMessage();
} finally {
    echo "Blok ini selalu dijalankan";
}
?>

Multiple Catch Blocks

<?php
function connectDatabase($host, $username, $password) {
    try {
        $pdo = new PDO("mysql:host=$host", $username, $password);
        return $pdo;
    } catch (PDOException $e) {
        echo "Database error: " . $e->getMessage();
        return false;
    } catch (Exception $e) {
        echo "General error: " . $e->getMessage();
        return false;
    }
}

$db = connectDatabase('localhost', 'user', 'password');
?>

Membuat Custom Exception

<?php
class CustomException extends Exception {
    public function errorMessage() {
        return "Custom Error: {$this->getMessage()} on line {$this->getLine()}";
    }
}

class ValidationException extends Exception {}

function validateAge($age) {
    if ($age < 0) {
        throw new ValidationException("Umur tidak boleh negatif");
    }
    if ($age > 150) {
        throw new ValidationException("Umur tidak realistis");
    }
    return true;
}

try {
    validateAge(-5);
} catch (ValidationException $e) {
    echo "Validation Error: " . $e->getMessage();
}
?>
Tips: Gunakan exception yang spesifik untuk error yang berbeda agar lebih mudah debugging dan handling.

Custom Error Handler

Membuat custom error handler memungkinkan kita mengontrol bagaimana error ditangani di seluruh aplikasi.

Custom Error Handler Function

<?php
function customErrorHandler($errno, $errstr, $errfile, $errline) {
    $errorTypes = [
        E_ERROR => 'FATAL ERROR',
        E_WARNING => 'WARNING',
        E_NOTICE => 'NOTICE',
        E_PARSE => 'PARSE ERROR',
        E_STRICT => 'STRICT'
    ];
    
    $errorType = isset($errorTypes[$errno]) ? $errorTypes[$errno] : 'UNKNOWN';
    
    $message = "[{$errorType}] {$errstr} in {$errfile} on line {$errline}";
    
    // Log error
    error_log($message);
    
    // Tampilkan pesan user-friendly
    if ($errno == E_ERROR || $errno == E_PARSE) {
        echo "Maaf, terjadi kesalahan sistem. Tim teknis telah diberitahu.";
        exit();
    }
    
    return true; // Mencegah PHP error handler default
}

// Set custom error handler
set_error_handler('customErrorHandler');
?>

Custom Exception Handler

<?php
function customExceptionHandler($exception) {
    // Log exception
    $message = "Uncaught exception: " . $exception->getMessage() . 
               " in " . $exception->getFile() . 
               " on line " . $exception->getLine();
    error_log($message);
    
    // Tampilkan pesan user-friendly
    echo "<h1>Oops! Something went wrong</h1>";
    echo "<p>We're sorry, but something went wrong. Please try again later.</p>";
    
    // Kirim email ke admin (opsional)
    if (class_exists('PHPMailer')) {
        // Send email notification
    }
}

set_exception_handler('customExceptionHandler');
?>

Shutdown Function untuk Fatal Errors

<?php
function shutdownHandler() {
    $error = error_get_last();
    
    if ($error && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR])) {
        $message = "Fatal Error: {$error['message']} in {$error['file']} on line {$error['line']}";
        error_log($message);
        
        // Tampilkan halaman error custom
        include 'error-page.html';
    }
}

register_shutdown_function('shutdownHandler');
?>
Best Practice: Kombinasikan error handler, exception handler, dan shutdown function untuk coverage error handling yang lengkap.

Error Logging

Logging error sangat penting untuk monitoring dan debugging aplikasi, terutama di environment production.

Basic Error Logging

<?php
// Enable error logging
ini_set('log_errors', 1);
ini_set('error_log', '/path/to/php-error.log');

// Manual logging
error_log("This is a custom error message");

// Logging dengan context
error_log("User login failed for: " . $_POST['username']);

// Logging dengan timestamp
error_log(date('[Y-m-d H:i:s] ') . "Error occurred");
?>

Advanced Logging Class

<?php
class Logger {
    private $logFile;
    
    public function __construct($logFile = 'app.log') {
        $this->logFile = $logFile;
    }
    
    public function log($level, $message, $context = []) {
        $timestamp = date('Y-m-d H:i:s');
        $contextString = empty($context) ? '' : ' | Context: ' . json_encode($context);
        
        $logEntry = "[{$timestamp}] {$level}: {$message}{$contextString}" . PHP_EOL;
        
        file_put_contents($this->logFile, $logEntry, FILE_APPEND | LOCK_EX);
    }
    
    public function error($message, $context = []) {
        $this->log('ERROR', $message, $context);
    }
    
    public function warning($message, $context = []) {
        $this->log('WARNING', $message, $context);
    }
    
    public function info($message, $context = []) {
        $this->log('INFO', $message, $context);
    }
    
    public function debug($message, $context = []) {
        $this->log('DEBUG', $message, $context);
    }
}

// Penggunaan
$logger = new Logger('errors.log');
$logger->error('Database connection failed', ['host' => 'localhost', 'port' => 3306]);
?>

Monitoring dan Alerting

<?php
class ErrorMonitor {
    private $logger;
    private $alertThreshold;
    private $errorCount = 0;
    
    public function __construct($logger, $alertThreshold = 10) {
        $this->logger = $logger;
        $this->alertThreshold = $alertThreshold;
    }
    
    public function handleError($errno, $errstr, $errfile, $errline) {
        $this->errorCount++;
        
        // Log error
        $this->logger->error($errstr, [
            'file' => $errfile,
            'line' => $errline,
            'type' => $errno
        ]);
        
        // Send alert if threshold exceeded
        if ($this->errorCount >= $this->alertThreshold) {
            $this->sendAlert();
            $this->errorCount = 0; // Reset counter
        }
        
        return true;
    }
    
    private function sendAlert() {
        // Send email, SMS, or push notification
        mail('admin@example.com', 'High Error Rate Alert', 
             'Error threshold exceeded on ' . $_SERVER['HTTP_HOST']);
    }
}
?>
Tips: Gunakan log rotation untuk mencegah file log menjadi terlalu besar, dan pertimbangkan menggunakan tools monitoring seperti Sentry atau New Relic.
Tutorial Saat Ini
Level: Menengah

Memerlukan pemahaman dasar PHP

Daftar Isi
Tips Belajar