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 Error | Contoh Error Code/Sub-Kode | Contoh Kasus |
---|---|---|
Syntax Error | 42601 (Postgres) | Typo pada query SQL (SELECT * FRM users; ) |
Connection Error | ECONNREFUSED, timeout | Database mati/layanan hang |
Data Constraint | unique_violation (23505 ) | Insert email user sudah ada, field email unique |
Deadlock | deadlock_detected (40P01 ) | 2 query menunggu satu sama lain |
Not Found | empty result set | Query mencari data yang sudah dihapus |
Authorization Error | insufficient_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!
57. Studi Kasus: Mengamankan API gRPC Internal
58. gRPC dengan JWT untuk Otentikasi
Artikel Terhangat
43 Testing Mutation dan Validasi Input
08 Aug 2025
65. gRPC Name Resolver Kustom
08 Aug 2025
42 Membuat Unit Test Query di graphql-go
08 Aug 2025
64. Implementasi gRPC Health Server
08 Aug 2025
41 Pengenalan Unit Test untuk Resolver
08 Aug 2025
63. gRPC Health Checking Standar
08 Aug 2025

43 Testing Mutation dan Validasi Input

65. gRPC Name Resolver Kustom

42 Membuat Unit Test Query di graphql-go

64. Implementasi gRPC Health Server

41 Pengenalan Unit Test untuk Resolver
