BAB 16 — Error Handling: Menangani Kesalahan di JavaScript

BAB 16 — Error Handling: Menangani Kesalahan di JavaScript

Error handling adalah bagian penting dari pengembangan JavaScript modern. Tanpa penanganan error yang tepat, aplikasi bisa crash, menyebabkan bug sulit dilacak, dan menghasilkan pengalaman pengguna yang buruk.

JavaScript menyediakan beberapa mekanisme untuk menangkap, memproses, dan melaporkan error, baik di synchronous maupun asynchronous code.


1. Try, Catch, Finally

try/catch/finally adalah cara dasar menangani error di JavaScript.

1.1 Struktur Dasar

try {
    // kode yang mungkin menimbulkan error
    let result = riskyOperation();
    console.log(result);
} catch (error) {
    // kode untuk menangani error
    console.error("Terjadi error:", error.message);
} finally {
    // kode yang selalu dijalankan
    console.log("Eksekusi selesai");
}
  • try → blok kode yang dicek error.
  • catch → menangkap error jika terjadi.
  • finally → dijalankan selalu, baik error terjadi maupun tidak. Cocok untuk cleanup, menutup loader, atau reset state.

1.2 Contoh Praktis

try {
    let json = JSON.parse('{"nama": "John"}'); // valid
    console.log(json.nama);
} catch (error) {
    console.error("Parsing gagal:", error);
} finally {
    console.log("Selesai parsing JSON");
}

Insight:

  • Gunakan finally untuk tugas yang selalu harus dijalankan, misal menutup koneksi atau menghentikan animasi loader.

2. Throw: Memicu Error Sendiri

Kita bisa membuat error secara manual dengan throw.

function checkAge(age) {
    if(age < 18) {
        throw new Error("Usia harus 18 tahun atau lebih");
    }
    return "Akses diberikan";
}

try {
    console.log(checkAge(16));
} catch (err) {
    console.error(err.message); // "Usia harus 18 tahun atau lebih"
}
  • throw → memicu error yang bisa ditangkap di catch.
  • Bisa digunakan untuk validasi input, logika bisnis, atau kondisi tak diinginkan.

3. Membuat Custom Error

Kita bisa membuat class error sendiri untuk kebutuhan spesifik.

class ValidationError extends Error {
    constructor(message) {
        super(message);
        this.name = "ValidationError";
    }
}

function validateUsername(username) {
    if(username.length < 5) {
        throw new ValidationError("Username terlalu pendek");
    }
    return true;
}

try {
    validateUsername("abc");
} catch (err) {
    if(err instanceof ValidationError) {
        console.error("Validation Error:", err.message);
    } else {
        console.error("Error lain:", err);
    }
}

Kelebihan:

  • Memisahkan error jenis berbeda.
  • Memudahkan error handling granular di aplikasi besar.

4. Error pada Asynchronous JavaScript

Error pada asynchronous code perlu perlakuan khusus, karena try/catch biasa tidak menangkap error di Promise atau async function kecuali await digunakan.

4.1 Error di Promise

Promise.reject("Promise gagal")
    .catch(err => console.error("Terjadi error:", err));

4.2 Error di Async/Await

async function fetchData() {
    try {
        const response = await fetch("https://api.invalidurl.com/data");
        const data = await response.json();
        console.log(data);
    } catch (error) {
        console.error("Async error:", error.message);
    } finally {
        console.log("Async operation selesai");
    }
}

fetchData();

Tips:

  • Selalu gunakan try/catch di fungsi async untuk menangani Promise yang rejected.
  • Gunakan .catch() di Promise chain untuk menangkap error pada callback.
  • Kombinasi try/catch + finally → aman untuk cleanup dan UX.

5. Praktik Terbaik Error Handling

  1. Tangkap error secara spesifik
    • Jangan menangkap semua error dengan catch(err) tanpa pengecekan, gunakan instanceof atau properti error.
  2. Gunakan custom error untuk kasus bisnis
    • Misal ValidationError, AuthenticationError, NetworkError.
  3. Async error handling
    • Gunakan try/catch di async/await.
    • Gunakan .catch() untuk Promise.
  4. Logging dan monitoring
    • Catat error ke console, server log, atau service monitoring.
    • Jangan hanya menampilkan alert di UI.
  5. Cleanup dengan finally
    • Tutup loader, release resource, reset state, terlepas error terjadi atau tidak.

6. Contoh Kasus Nyata

6.1 Form Validation

function validateForm(data) {
    if(!data.email.includes("@")) {
        throw new ValidationError("Email tidak valid");
    }
}

try {
    validateForm({email: "test.com"});
} catch (err) {
    console.error(err.name, ":", err.message);
}

6.2 Fetch API dengan Error Handling

async function getUserData() {
    try {
        const response = await fetch("https://jsonplaceholder.typicode.com/users/1000");
        if(!response.ok) throw new Error("User tidak ditemukan");
        const user = await response.json();
        console.log(user);
    } catch (error) {
        console.error("Fetch error:", error.message);
    } finally {
        console.log("Fetch selesai");
    }
}

getUserData();

7. Kesimpulan

  • Error handling adalah kunci stabilitas dan UX aplikasi web.
  • try/catch/finally → menangani error synchronous.
  • throw → memicu error sendiri untuk validasi dan logika bisnis.
  • Custom Error → memisahkan jenis error untuk penanganan granular.
  • Error asynchronous → tangani dengan try/catch di async/await atau .catch() di Promise.
  • Praktik terbaik → spesifik, konsisten, logging, cleanup dengan finally.

💡 Insight: Tanpa error handling yang baik, aplikasi rentan crash, data hilang, dan debugging menjadi sulit. Menguasai error handling adalah fondasi penting bagi developer profesional.