您好,登錄后才能下訂單哦!
這篇文章將為大家詳細(xì)講解有關(guān)如何利用express異步函數(shù)對(duì)異常進(jìn)行捕獲,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。
在express中時(shí)使用 Async/await 編寫異步代碼時(shí),每個(gè) async 函數(shù)都要包裹在try/catch中,代碼量多了看著冗余不優(yōu)雅,express又不像koa的異步機(jī)制可以訂閱全局的error事件,為了解決這個(gè)問題,需要寫個(gè)捕獲異步函數(shù)異常的中間件。
開始能想到的肯定是try/catch了,但是也想過能否使用nodejs提供的uncaughtException事件,在全局捕獲異常,例如下面的代碼:
process.on("uncaughtException", (err) => console.log("uncaught Exception")); const asyncError=()=>{ throw new Error("some Error"); } asyncError();
asyncError方法里面拋出的異常會(huì)被 uncaughtException訂閱,但是在異步函數(shù)中,并沒走到 uncaughtException,還是會(huì)拋出異常:
process.on("uncaughtException", (err) => console.log("uncaught Exception")); const asyncError=()=>{ throw new Error("some Error"); } (async ()=>{ // 拋出異常 asyncError(); })()
而且Promise.reject也沒走到uncaughtException里面:
const asyncError=()=>{ return Promise.reject("some error") } (async ()=>{ // 拋出異常 await asyncError(); })()
所以在express中使用nodejs提供的uncaughtException處理異步錯(cuò)誤不太合適,一方面沒法捕獲和定位上下文錯(cuò)誤,另一方面也沒法將錯(cuò)誤異常提供給中間件函數(shù)處理
要處理express中的異步函數(shù)錯(cuò)誤,最好的方法當(dāng)然是編寫處理異常的中間件了,try/catch開路,包裹中間件方法,catch到的異常直接交給next函數(shù)處理,代碼如下:
const asyncHandler = fn =>{ return (req,res,next)=>{ try{ fn(req,res,next) }catch(next) } } module.exports = asyncHandler;
接下來,在異步函數(shù)中引入中間件處理:
app.use(asyncHandler(async(req, res, next) => { await authenticate(req); next(); })); app.get('/async', asyncHandler(async(req, res) => { const result = await request('http://example.com'); res.end(result); }));
使用asyncHandler方法包裹的async/await函數(shù),如果出現(xiàn)錯(cuò)誤就會(huì)被Error-handling中間件捕獲了
但是每次用到異步函數(shù)的時(shí)候都要包裹asyncHandler方法,真正用起來也不是很爽,這里推薦使用express-async-errors中間件,其原理是將express里面的中間全部包裹上一層asyncHandler方法,讓錯(cuò)誤異常無所遁形,全部跑到Error-handling中間件。
前提是引入express后,先引入express-async-errors方法:
const express = require('express'); require('express-async-errors'); const User = require('./models/user'); const app = express(); app.get('/users', async (req, res) => { const users = await User.findAll(); res.send(users); });
接下來的在異步函數(shù)中,就不用都包裹上try/catch了,有錯(cuò)誤提前throw Error,寫起代碼來美滋滋:
app.use(async (req, res) => { const user = await User.findByToken(req.get('authorization')); if (!user) throw Error("access denied"); }); app.use((err, req, res, next) => { if (err.message === 'access denied') { res.status(403); res.json({ error: err.message }); } next(err); });~~~~
關(guān)于如何利用express異步函數(shù)對(duì)異常進(jìn)行捕獲就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。