Error Handler di ExpressJS

Alif Rizki
SkyshiDigital
Published in
4 min readAug 31, 2018
https://amandeepmittal.gallerycdn.vsassets.io/extensions/amandeepmittal/expressjs/2.0.0/1509881293872/Microsoft.VisualStudio.Services.Icons.Default

Bagi teman-teman yang baru mulai menginjakkan kakinya di dunia Node.js, ExpressJS merupakan framework wajib yang harus kalian pelajari dari sekian banyaknya framework web application Node.js yang ada. Dan banyak juga framework-framework Node.js lain yang menggunakan ExpressJS sebagain pondasinya, seperti; Feathers, LoopBack, MEAN, Sails, NestJS, dan sebagainya yang bisa kalian lihat disini.

Pada artikel kali ini, saya tidak akan membahas tentang bagaimana membuat web application dengan ExpressJS ataupun membuat RESTful API dengan ExpressJS. Tapi kali saya akan membahas dan memberikan sedikit tips bagaimana menangani Error pada ExpressJS, agar code kita menjadi lebih rapi.

Persiapan

Untuk persiapan mari kita buat folder baru lalu menjalankan npm init untuk menginisialisasi project Node.js baru.

Lalu kita buat file app.js yang berisi seperti berikut:

app.js

Sedikit penjelasan mengenai kode diatas. Kode diatas menggunakan express Router , Router itu ibarat mini express application yang menyediakan routing API seperti .all , .METHOD , .param , .route , dan .use . Untuk penjelasan lengkap nya bisa kalian baca disini.

Terdapat 1 router untuk meng-handle /status yang akan memberikan response Status OK. Running....

Dibawah terdapat juga error handler yang berguna untuk menangkap semua dan menampilkan response error ke user yang dilemparkan dari controller/middleware melalui next(error). Contohnya misal kita ubah code router /status menjadi seperti ini:

// Router for /status
router.get('/status',
(req, res, next) => {
return next(new Error('Contoh Error'));
res.json({
status: true,
code: 200,
message: 'Status OK. Running...',
data: {},
})
}
)

Restart aplikasinya, lalu kita buka lagi di browser maka akan muncul response seperti ini.

Contoh Error

Sedikit informasi tentang express Router, sebenarnya express Router ini secara otomatis akan menangkap unhandled exception . Jadi tanpa kita next pun, express Router akan secara otomatis melempar Error ke error handler yang ada dibawah. Misal kita ubah codenya menjadi seperti ini maka akan menghasilkan response yang sama di browser.

// Router for /status
router.get('/status',
(req, res) => {
throw new Error('Contoh Error');
res.json({
status: true,
code: 200,
message: 'Status OK. Running...',
data: {},
})
}
)

Unhandled Rejection

Masalah baru muncul apabila controller/middleware kita berupa async function. Kita tidak bisa langsung melempar Error ke error handler dengan throw new Error , karena akan muncul unhandled rejection yang akan membuat aplikasi kita crash. Jadi kita harus menggunakan next() untuk melempar Error ke error handler. Akan tetapi cara ini akan membuat kita terlalu banyak menggunakan try...catch... didalam controller/middleware. Lalu, bagaimanakah solusi terbaik untuk menangani unhandled rejection ini supaya tidak terlalu banyak try...catch...? Berikut caranya;

Pertama kita buat sebuah function yang berfungsi sebagai wrapper untuk async controller/middleware.

const wrap = fn => (req, res, next) => {
try {
const result = fn(req, res, next);
return result.catch(next);
} catch (err) {
return next(err);
}
};

Lalu kita buat async controller baru,

const JOKES_URL = 'https://08ad1pao69.execute-api.us-east-1.amazonaws.com/dev/random_joke';const getJoke = async (req, res) => {
const joke = await axios.get(JOKES_URL);
res.json({
status: true,
code: 200,
message: 'Success',
data: joke.data || joke,
})
}

Buat routernya

router.get('/joke', wrap(getJoke));

Lalu kita restart aplikasinya dan buka di browser. Maka akan mendapat response success seperti dibawah ini.

Selanjutnya mari kita coba membuat error dengan mengganti JOKES_URL seperti dibawah ini

const getJoke = async (req, res) => {
const joke = await axios.get(JOKES_URL + '/error');
res.json({
status: true,
code: 200,
message: 'Success',
data: joke.data || joke,
})
}

Restart aplikasinya lalu lihat di browsernya. Maka akan mendapat response error seperti ini dan tanpa mengalami crash aplikasi.

Bonus

Jika dalam 1 router terdapat banyak controller/middleware, maka kita harus melakukan wrapper kepada semua controller/middleware yang ada satu persatu. Kami sudah membuat sebuah library untuk mengatasi hal tersebut. Intinya kita cukup menggunakan 1 wrapper untuk 1 router, tanpa perlu wrapping controller/middleware satu persatu.

Librarynya sendiri diberi nama Promise Router Monitor. Untuk tutorial dan bagaimana cara menggunakannya, bisa kalian lihat di link yang ada dibawah. Untuk penjelasan lebih lanjut mengenai Promise Router Monitor mungkin akan saya bahas di artikel selanjutnya.

Cukup sekian artikel dari saya. Sampai jumpa di artikel selanjutnya. Semoga bermanfaat.

--

--