Koa 中的錯誤處理


不像 express 中在末尾處注冊一個聲明為 (err, req, res, next) 中間件的方式,koa 剛好相反,在開頭進行注冊。

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);
  }
});

這樣程序中任何報錯都會收斂到此處。此時可以方便地將錯誤打印到頁面,開發時非常便捷。

+     ctx.app.emit('error', err, ctx);

koa 也建議通過 app 來派發錯誤,然后通過監聽 app 上的 error 事件對這些錯誤做進一步的統一處理和集中管理。

app.on("error", (err, ctx) => {
  /* 錯誤的集中處理:
   *  log 出來
   *  寫入日志
   *  寫入數據庫
   *   ...
   */
});

一個錯誤捕獲並打印到頁面的示例:

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 = </span></span> <span class="pl-s"> &lt;b&gt;<span class="pl-s1"><span class="pl-pse">${</span>status<span class="pl-pse">}</span></span>&lt;/b&gt; <span class="pl-s1"><span class="pl-pse">${</span>err<span class="pl-pse">}</span></span></span> <span class="pl-s"> <span class="pl-pds">;
// 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);

通過 node server.js 啟動后訪問頁面可看到命令行的錯誤輸出。
如果使用 pm2,可通過 —no-daemon 參數使其停留在在命令行以查看輸出。
如果不使用上述參數,可通過 pm2 logs [app-name] 來查看。

ctx.throw

朴素的拋錯方式需要手動設置狀態碼及信息對客戶端的可見性。

const err = new Error("err msg");
err.status = 401;
err.expose = true;
throw err;

expose 決定是否會返回錯誤詳情給客戶端,否則只展示狀態對應的錯誤文案,比如 500 會在瀏覽器中展示為 Internal Server Error

而通過 ctx.throw 這個 helper 方法會更加簡潔。
上面的代碼片段等價於:

ctx.throw(401, "err msg");

如果不指定狀態碼,默認為 500。5xx 類錯誤 expose 默認為 false,即不會將錯誤信息返回到 response。

拋錯時還可以傳遞一些額外數據,這些數據會合並到錯誤對象上,在處理錯誤的地方可以從 error 上獲取。

app.use(ctx => {
  ctx.throw(401, "access_denied", { user: { name: "foo" } });
});

app.on("error", (err, ctx) => {
console.error("Ooops..\n", err.user);
});

參考


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM