摘要:處理異常是編程非常重要的一點(diǎn)。我們的程序依賴于第三方服務(wù)數(shù)據(jù)庫以及我們的用戶,一切都不可預(yù)料。為了處理這些錯(cuò)誤,需要添加一個(gè)中間件,它有個(gè)參數(shù)這樣,我們就可以使用中間件統(tǒng)一處理錯(cuò)誤了。
譯者按:根據(jù)墨菲定律:“有可能出錯(cuò)的事情,就會(huì)出錯(cuò)”。那么,既然代碼必然會(huì)出錯(cuò),我們就應(yīng)該處理好異常。
原文: How to handle errors in Express
譯者:Fundebug
為了保證可讀性,本文采用意譯而非直譯。另外,本文版權(quán)歸原作者所有,翻譯僅用于學(xué)習(xí)。
處理異常是編程非常重要的一點(diǎn)。我們的程序依賴于第三方服務(wù)、數(shù)據(jù)庫以及我們的用戶,一切都不可預(yù)料。數(shù)據(jù)庫可能會(huì)宕機(jī),第三方服務(wù)可能會(huì)崩潰,用戶可能會(huì)使用錯(cuò)誤的參數(shù)調(diào)用我們的接口。
為了處理各種復(fù)雜的情況,我們必須處理好代碼異常,下面是代碼示例:
app.get("/users/:id", (req, res) => { const userId = req.params.id if (!userId) { return res.sendStatus(400).json({ error: "Missing id" }) } Users.get(userId, (err, user) => { if (err) { return res.sendStatus(500).json(err) } res.send(users) }) })
代碼中處理了異常,但是存在問題:
在多處代碼處理異常
沒有使用Express的異常處理模塊來統(tǒng)一處理異常
接下來,我們來一步步優(yōu)化代碼異常處理。
Express異常處理中間件所有Express的路由處理函數(shù)都有第三個(gè)參數(shù)next,它可以用來調(diào)用下一個(gè)中間件,也可以將錯(cuò)誤傳遞給錯(cuò)誤處理中間件:
app.get("/users/:id", (req, res, next) => { const userId = req.params.id if (!userId) { const error = new Error("missing id") error.httpStatusCode = 400 return next(error) } Users.get(userId, (err, user) => { if (err) { err.httpStatusCode = 500 return next(err) } res.send(users) }) })
使用next(err),Express就知道出錯(cuò)了,并把這個(gè)錯(cuò)誤傳遞給錯(cuò)誤處理模塊。為了處理這些錯(cuò)誤,需要添加一個(gè)中間件,它有4個(gè)參數(shù):
app.use((err, req, res, next) => { // log the error... res.sendStatus(err.httpStatusCode).json(err) })
這樣,我們就可以使用中間件統(tǒng)一處理錯(cuò)誤了。但是,現(xiàn)在的代碼有些重復(fù):創(chuàng)建錯(cuò)誤,指定HTTP狀態(tài)碼,使用next(err)...
Fundebug是全棧JavaScript錯(cuò)誤監(jiān)控平臺(tái),支持各種前端和后端框架,可以幫助您第一時(shí)間發(fā)現(xiàn)BUG!
boomboom是一個(gè)兼容HTTP的錯(cuò)誤對象,他提供了一些標(biāo)準(zhǔn)的HTTP錯(cuò)誤,比如400(參數(shù)錯(cuò)誤)等。
const boom = require("boom") app.get("/users/:id", (req, res, next) => { const userId = req.params.id if (!userId) { return next(boom.badRequest("missing id")) } Users.get(userId, (err, user) => { if (err) { return next(boom.badImplementation(err)) } res.send(users) }) })
錯(cuò)誤處理中間件需要稍作修改:
app.use((err, req, res, next) => { if (err.isServer) { // log the error... // probably you don"t want to log unauthorized access // or do you? } return res.status(err.output.statusCode).json(err.output.payload); })Async/Await錯(cuò)誤處理
使用Async/Await之后,可以這樣處理Express異常:
將中間件使用Promise封裝起來,使用catch統(tǒng)一處理異常
在中間件中,直接拋出異常就可以了
const boom = require("boom"); // wrapper for our async route handlers // probably you want to move it to a new file const asyncMiddleware = fn => (req, res, next) => { Promise.resolve(fn(req, res, next)).catch((err) => { if (!err.isBoom) { return next(boom.badImplementation(err)); } next(err); }); }; // the async route handler app.get("/users/:id", asyncMiddleware(async (req, res) => { const userId = req.params.id if (!userId) { throw boom.badRequest("missing id") } const user = await Users.get(userId) res.json(user) }))參考
驗(yàn)證HTTP請求參數(shù)可以使用joi模塊
打印日志可以使用winston或者pino模塊
版權(quán)聲明:
轉(zhuǎn)載時(shí)請注明作者Fundebug以及本文地址:
https://blog.fundebug.com/2017/12/06/handle-express-error/
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/90461.html
摘要:第一個(gè)是,是你傳遞給異常的構(gòu)造函數(shù)的參數(shù),比如你可以使用屬性來訪問到該消息第二個(gè)參數(shù)是異常堆棧跟蹤,非常重要。異常產(chǎn)生后能在后端正確處理是的關(guān)鍵部分。我將向你展示自定義構(gòu)造函數(shù)和錯(cuò)誤代碼的方法,我們可以輕松地將其傳遞給前端或任何調(diào)用者。 By Lukas Gisder-Dubé | nov 14, 2018 原文 接著我上一篇文章,我想談?wù)劗惓?。我肯定你之前也聽過——異常是個(gè)好東西。一...
摘要:又或者反過來,把錯(cuò)誤當(dāng)成異常來處理。當(dāng)然,我猜它的目的,應(yīng)該也是為了能實(shí)現(xiàn)錯(cuò)誤與異常之間優(yōu)雅轉(zhuǎn)換而添加的。至此,錯(cuò)誤與異常的學(xué)習(xí)基本完畢。 這話題已經(jīng)沒有什么新意了,這里只是做做筆記,作為思路的一種整理,也以便后續(xù)忘了可以回來這里查找。 錯(cuò)誤 以下是 PHP 最常見的幾種錯(cuò)誤: // E_NOTICE echo $a; // E_WARNING echo 100 / 0; clas...
摘要:異常異常的概述和分類異常的概述異常就是程序在運(yùn)行過程中出現(xiàn)的錯(cuò)誤。運(yùn)行時(shí)異常就是程序員所犯的錯(cuò)誤,需要回來修改代碼。獲取異常類名和異常信息,返回字符串。如果路徑名不同,就是改名并剪切。刪除注意事項(xiàng)中的刪除不走回收站。 1_異常(異常的概述和分類) A:異常的概述 異常就是Java程序在運(yùn)行過程中出現(xiàn)的錯(cuò)誤。 B:異常的分類 通過API查看Throwable Error 服務(wù)...
摘要:在掘金摸魚的時(shí)候看到了一個(gè)題第題搜索如何防抖,如何處理中文輸入,感覺挺有意思的。測試地址事件輸入法事件輸入法的第一個(gè)字母時(shí)觸發(fā)。輸入法狀態(tài)輸入內(nèi)容。輸入法選擇之后觸發(fā)。 前端最基礎(chǔ)的就是 HTML+CSS+Javascript。掌握了這三門技術(shù)就算入門,但也僅僅是入門,現(xiàn)在前端開發(fā)的定義已經(jīng)遠(yuǎn)遠(yuǎn)不止這些。前端小課堂(HTML/CSS/JS),本著提升技術(shù)水平,打牢基礎(chǔ)知識的中心思想,我...
摘要:在掘金摸魚的時(shí)候看到了一個(gè)題第題搜索如何防抖,如何處理中文輸入,感覺挺有意思的。測試地址事件輸入法事件輸入法的第一個(gè)字母時(shí)觸發(fā)。輸入法狀態(tài)輸入內(nèi)容。輸入法選擇之后觸發(fā)。 前端最基礎(chǔ)的就是 HTML+CSS+Javascript。掌握了這三門技術(shù)就算入門,但也僅僅是入門,現(xiàn)在前端開發(fā)的定義已經(jīng)遠(yuǎn)遠(yuǎn)不止這些。前端小課堂(HTML/CSS/JS),本著提升技術(shù)水平,打牢基礎(chǔ)知識的中心思想,我...
閱讀 3499·2023-04-25 21:43
閱讀 3109·2019-08-29 17:04
閱讀 814·2019-08-29 16:32
閱讀 1548·2019-08-29 15:16
閱讀 2161·2019-08-29 14:09
閱讀 2754·2019-08-29 13:07
閱讀 1638·2019-08-26 13:32
閱讀 1331·2019-08-26 12:00