不像 express 中在末尾處注冊(cè)一個(gè)聲明為 (err, req, res, next) 中間件的方式,koa 剛好相反,在開(kāi)頭進(jìn)行注冊(cè)。
10年積累的成都做網(wǎng)站、成都網(wǎng)站建設(shè)經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶(hù)對(duì)網(wǎng)站的新想法和需求。提供各種問(wèn)題對(duì)應(yīng)的解決方案。讓選擇我們的客戶(hù)得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先網(wǎng)站設(shè)計(jì)后付款的網(wǎng)站建設(shè)流程,更有昆明免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。
app.use(async (ctx, next) => { try { await next(); } catch (err) { ctx.status = err.status || 500; ctx.body = err.message; ctx.app.emit("error", err, ctx); } });
這樣程序中任何報(bào)錯(cuò)都會(huì)收斂到此處。此時(shí)可以方便地將錯(cuò)誤打印到頁(yè)面,開(kāi)發(fā)時(shí)非常便捷。
+ ctx.app.emit('error', err, ctx);
koa 也建議通過(guò) app 來(lái)派發(fā)錯(cuò)誤,然后通過(guò)監(jiān)聽(tīng) app 上的 error 事件對(duì)這些錯(cuò)誤做進(jìn)一步的統(tǒng)一處理和集中管理。
app.on("error", (err, ctx) => { /* 錯(cuò)誤的集中處理: * log 出來(lái) * 寫(xiě)入日志 * 寫(xiě)入數(shù)據(jù)庫(kù) * ... */ });
一個(gè)錯(cuò)誤捕獲并打印到頁(yè)面的示例:
const Koa = require("koa"); const app = new Koa(); app.use(async (ctx, next) => { try { await next(); } catch (err) { const status = err.status || 500; ctx.status = status; ctx.type = "html"; ctx.body = ` ${status} ${err} `; // emmit ctx.app.emit("error", err, ctx); } }); app.use(ctx => { const a = "hello"; a = "hello world!"; // TypeError: Assignment to constant variable. ctx.body = a; }); app.on("error", (err, ctx) => { console.error("Ooops..\n", err); }); app.listen(3000);
通過(guò) node server.js 啟動(dòng)后訪(fǎng)問(wèn)頁(yè)面可看到命令行的錯(cuò)誤輸出。
如果使用 pm2,可通過(guò) —no-daemon 參數(shù)使其停留在在命令行以查看輸出。
如果不使用上述參數(shù),可通過(guò) pm2 logs [app-name] 來(lái)查看。
ctx.throw
樸素的拋錯(cuò)方式需要手動(dòng)設(shè)置狀態(tài)碼及信息對(duì)客戶(hù)端的可見(jiàn)性。
const err = new Error("err msg"); err.status = 401; err.expose = true; throw err;
expose 決定是否會(huì)返回錯(cuò)誤詳情給客戶(hù)端,否則只展示狀態(tài)對(duì)應(yīng)的錯(cuò)誤文案,比如 500 會(huì)在瀏覽器中展示為 Internal Server Error 。
而通過(guò) ctx.throw
這個(gè) helper 方法會(huì)更加簡(jiǎn)潔。
上面的代碼片段等價(jià)于:
ctx.throw(401, "err msg");
如果不指定狀態(tài)碼,默認(rèn)為 500。5xx 類(lèi)錯(cuò)誤 expose 默認(rèn)為 false ,即不會(huì)將錯(cuò)誤信息返回到 response。
拋錯(cuò)時(shí)還可以傳遞一些額外數(shù)據(jù),這些數(shù)據(jù)會(huì)合并到錯(cuò)誤對(duì)象上,在處理錯(cuò)誤的地方可以從 error 上獲取。
app.use(ctx => { ctx.throw(401, "access_denied", { user: { name: "foo" } }); }); app.on("error", (err, ctx) => { console.error("Ooops..\n", err.user); });
參考
Error Handling
ctx.throw
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。