zoukankan      html  css  js  c++  java
  • 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.. ", 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.. ", err.user);
    });

    参考

  • 相关阅读:
    CodeForces 156B Suspects(枚举)
    CodeForces 156A Message(暴力)
    CodeForces 157B Trace
    CodeForces 157A Game Outcome
    HDU 3578 Greedy Tino(双塔DP)
    POJ 2609 Ferry Loading(双塔DP)
    Java 第十一届 蓝桥杯 省模拟赛 19000互质的个数
    Java 第十一届 蓝桥杯 省模拟赛 19000互质的个数
    Java 第十一届 蓝桥杯 省模拟赛 19000互质的个数
    Java 第十一届 蓝桥杯 省模拟赛十六进制转换成十进制
  • 原文地址:https://www.cnblogs.com/Wayou/p/error_handling_in_koajs.html
Copyright © 2011-2022 走看看