express異步函數異常捕獲示例詳解
在express中時使用 Async/await 編寫異步代碼時,每個 async 函數都要包裹在try/catch中,代碼量多了看著冗余不優(yōu)雅,express又不像koa的異步機制可以訂閱全局的error事件,為了解決這個問題,需要寫個捕獲異步函數異常的中間件。
uncaughtException
開始能想到的肯定是try/catch了,但是也想過能否使用nodejs提供的uncaughtException事件,在全局捕獲異常,例如下面的代碼:
process.on("uncaughtException", (err) => console.log("uncaught Exception"));
const asyncError=()=>{
throw new Error("some Error");
}
asyncError();
asyncError方法里面拋出的異常會被 uncaughtException訂閱,但是在異步函數中,并沒走到 uncaughtException,還是會拋出異常:
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處理異步錯誤不太合適,一方面沒法捕獲和定位上下文錯誤,另一方面也沒法將錯誤異常提供給中間件函數處理
解決思路
要處理express中的異步函數錯誤,最好的方法當然是編寫處理異常的中間件了,try/catch開路,包裹中間件方法,catch到的異常直接交給next函數處理,代碼如下:
const asyncHandler = fn =>{
return (req,res,next)=>{
try{
fn(req,res,next)
}catch(next)
}
}
module.exports = asyncHandler;
接下來,在異步函數中引入中間件處理:
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函數,如果出現錯誤就會被Error-handling中間件捕獲了
但是每次用到異步函數的時候都要包裹asyncHandler方法,真正用起來也不是很爽,這里推薦使用express-async-errors中間件,其原理是將express里面的中間全部包裹上一層asyncHandler方法,讓錯誤異常無所遁形,全部跑到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);
});
接下來的在異步函數中,就不用都包裹上try/catch了,有錯誤提前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);
});~~~~
參考鏈接:
到此這篇關于express異步函數異常捕獲示例的文章就介紹到這了,更多相關express異步函數異常捕獲內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
讓iframe子窗體取父窗體地址欄參數(querystring)
突然用到,記錄一下,對地址欄字符串用正則處理最好,有時間研究一下。 主要是思路。2009-10-10
關于document.cookie的使用javascript
設置cookie 每個cookie都是一個名/值對,可以把下面這樣一個字符串賦值給document.cookie:2008-04-04
發(fā)布BlueShow v1.0 圖片瀏覽器(類似lightbox)blueshow.js 打包下載
發(fā)布BlueShow v1.0 圖片瀏覽器(類似lightbox)blueshow.js 打包下載...2007-07-07

