tutorial

35 Penanganan Error Database dalam Resolver

35 Penanganan Error Database dalam Resolver

Penanganan error merupakan aspek fundamental dalam membangun aplikasi back-end, terutama pada layer resolver di GraphQL atau REST API. resolver berfungsi sebagai perantara antara permintaan pengguna dan data yang diolah di database. Sayangnya, interaksi dengan database sangat rentan terhadap berbagai error—mulai dari error sintaks SQL, koneksi timeout, hingga data constraint violation. Dalam artikel ini, saya akan membagikan 35 cara penanganan error database di resolver, lengkap beserta contoh kode, simulasi, dan diagram flow agar produk yang kita develop semakin robust.


Mengapa Error Handling pada Database itu Penting?

Gagal menangani error database bisa berdampak buruk:

  • Data corruption: jika transaksi tidak di-rollback.
  • Service downtime: misal koneksi database gagal dikelola dengan baik.
  • User experience buruk: pesan error tidak informatif atau bahkan bocornya detail internal.
  • Kebocoran security: stacktrace “nyeleneh” sampai ke frontend.

Tipe Error yang Muncul di Database

Tabel berikut menggambarkan beberapa tipe error database beserta contohnya:

Kategori ErrorContoh Error Code/Sub-KodeContoh Kasus
Syntax Error42601 (Postgres)Typo pada query SQL (SELECT * FRM users;)
Connection ErrorECONNREFUSED, timeoutDatabase mati/layanan hang
Data Constraintunique_violation (23505)Insert email user sudah ada, field email unique
Deadlockdeadlock_detected (40P01)2 query menunggu satu sama lain
Not Foundempty result setQuery mencari data yang sudah dihapus
Authorization Errorinsufficient_privilege (42501)User DB tidak punya akses baca tabel tertentu

Diagram Alur Penanganan Error di Resolver

Mari kita lihat diagram alur sederhana apa yang terjadi ketika query kita eksekusi di resolver dan menghadapi error:

flowchart TD
  A[Client Request] --> B{Resolver}
  B --> C{DB Query}
  C -- Success --> D[Return Data]
  C -- Error --> E{Type of Error}
  E -- Connection/Timeout --> F[Log & Return 503]
  E -- Not Found --> G[Return Null / NotFound Err]
  E -- Constraint --> H[Return 400/409 & Custom Error]
  E -- Unknown --> I[Log Detail & Return 500]
  F --> J[Client]
  G --> J
  H --> J
  I --> J

35 Pola Penanganan Error Database dalam Resolver

1. Gunakan Try-Catch Blok

async function resolver(_, args, context) {
  try {
    return await db.query('SELECT * FROM ...');
  } catch (err) {
    console.error('DB Error:', err);
    throw new Error('Internal Server Error');
  }
}

2. Mapping Error Code ke Pesan yang Tepat

Buat map error code DB ke pesan API.

const errorMap = {
  '23505': 'Duplicate entry',       // Unique constraint
  '42601': 'Syntax Error',
};

catch (err) {
  const message = errorMap[err.code] || 'Internal Error';
  throw new Error(message);
}

3. Gunakan Custom Error Class

class NotFoundError extends Error {}
class ValidationError extends Error {}

4. Error Logging Lengkap namun Aman

Log pesan lengkap ke server, tampilkan ringkas ke client.

5. Lakukan Retry pada Connection Error

async function queryWithRetry() {
  for (let i = 0; i < 3; i++) {
    try return await db.query(...);
    catch (err) {
      if (isConnectionError(err)) await sleep(100);
      else throw err;
    }
  }
  throw new Error('Cannot connect to DB');
}

6. Rollback Transaksi pada Error

try {
  await db.begin();
  await db.query('...');
  await db.commit();
} catch (e) {
  await db.rollback();
  throw e;
}

7. Standardisasi Response Error

Buat format error:

{
  "code": "CONFLICT",
  "message": "Duplicate record",
  "details": "users.email must be unique"
}

8. Pisahkan Internal dan User Error

Error DB internal jangan pernah “bocor” ke client.

9. Gunakan Error Boundaries di Layer Service/Use Case

10. Validasi Data Input sebelum Query

11. Graceful Fallback untuk Not Found

if (result.rows.length === 0) return null; 

12. Return Null serta pesan error sesuai GraphQL spec

13. Pakai Library Error Handling

Seperti Boom untuk REST.

14. Gunakan Deadlock/Timeout Detector

15. Implementasikan Exponential Backoff pada Retry

16. Documentasikan Error yang Terjadi

Simpan log kode error DB dan mapping di dokumen.

17. Konsisten pada HTTP Code

409 untuk duplicate, 404 jika tidak ketemu, 500 untuk error dalam.

18. Hindari SQL Injection (validasi input & parameterized query)

19. Jangan Tampilkan Stacktrace ke Client

20. Simpan Error di Error Monitoring Tool

Seperti Sentry, Datadog.

21. Tampilkan Error-Friendly Message untuk User

Contoh: “Email sudah digunakan”, bukan “23505 unique_violation”.

22. Test Error Path dengan Unit Test

23. Pastikan Koneksi DB Selalu Ditutup

Dengan Pooling/Auto-close.

24. Handle Query Timeout

25. Pastikan Transaksi Atomic

26. Gunakan Isolation Level pada Transaksi

27. Ambil Pesan Error DB Lokal (locale message)

Agar user friendly.

28. Rate Limit pada Query Error berulang

Agar tidak ddos/konsisten clog server.

29. Blacklist/Ban IP abusive error

30. Handle Error DB Multi Shard/Microservice

31. Buat Error Metrics & Health Check Khusus DB

32. Replay Request jika idempotent

33. Hindari Redundant Query jika DB sedang Degraded

34. Gunakan CQRS/Read-Write Split pada Load Tinggi

35. Audit Log Semua Error Penting untuk Investigasi


Simulasi (Node.js/Express + PostgreSQL)

Mari simulasi handler error unik: duplicate key.

const { Pool } = require('pg');
const db = new Pool();

async function createUser(email) {
  try {
    await db.query('INSERT INTO users(email) VALUES($1)', [email]);
    return { success: true };
  } catch (err) {
    if (err.code === '23505') {
      // Unique violation
      throw new Error('Email sudah terdaftar');
    }
    // Log error detail
    console.error('[DB]', err);
    throw new Error('Terjadi error saat membuat user');
  }
}

Penutup

Menangani error database di resolver bukan hanya soal menulis “catch” di tiap fungsi, tapi mengintegrasikan best practice pada tiap layer, mendokumentasikan error, serta menyesuaikan level pesan pada masing-masing audience (dev vs user). Dengan 35 strategi di atas, Anda bisa memperkuat aplikasi dari error database baik skala kecil hingga enterprise.

Jangan ragu untuk menyesuaikan dan mengombinasikan teknik di atas agar error handling tetap scalable dan mudah di-debug.

Happy coding, dan semoga error tidak menghantui production Anda!

comments powered by Disqus

Topik Terhangat

programming
263
tutorial
130
tips-and-trick
43
jaringan
28
hardware
11
linux
4
kubernetes
1