不像 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);

});

参考

Koa 中的错误处理的更多相关文章

  1. koa中返回404并且刷新后才正常的解决方案

    概述 这几天学习koa2,有一些心得,记录下来,供以后开发时参考,相信对其他人也有用. 起因 这几天学习koa2,写的代码执行时有一个奇怪的bug:明明能够返回数据,却有时正常返回数据,有时偏偏给你返 ...

  2. Koa 框架 的错误处理

    默认情况下Koa会将所有错误信息输出到 stderr,除非 NODE_ENV 是 "test".为了实现自定义错误处理逻辑(比如 centralized logging),您可以添 ...

  3. Restful API 中的错误处理

    简介 随着移动开发和前端开发的崛起,越来越多的 Web 后端应用都倾向于实现 Restful API. Restful API 是一个简单易用的前后端分离方案,它只需要对客户端请求进行处理,然后返回结 ...

  4. 【转】SQL Server -- 已成功与服务器建立连接,但是在登录过程中发生错误

    SQL Server -- 已成功与服务器建立连接,但是在登录过程中发生错误 最近在VS2013上连接远程数据库时,突然连接不上,在跑MSTest下跑的时候,QTAgent32 crash.换成IIS ...

  5. vs2015 编译时错误列表中没有错误,dll却没有生成出来

    最近发现vs2015的一个问题, 编译时,错误列表中没有错误,dll却没有生成出来,vs重启也无效 解决: 多次排查发现如果一个类库设置的是framework 4.0版本,但引用了framework4 ...

  6. PHP中的错误处理、异常处理机制详解

    在编写PHP程序时,错误处理是一个重要的部分.如果程序中缺少错误检测代码,那么看上去很不专业,也为安全风险敞开了大门 例: <?php $a = fopen('test.txt','r'); / ...

  7. ASP.NET MVC中的错误处理

    ASP.NET MVC中的错误的错误处理跨越了两个主要领域:程序异常和路由异常的处理.前者是关于在控制器和视图中捕获错误的;而后者更多是有关重定向和HTTP错误的. 1.在WebConfig中把过滤器 ...

  8. javascript中的错误处理机制

    × 目录 [1]对象 [2]类型 [3]事件[4]throw[5]try[6]常见错误 前面的话 错误处理对于web应用程序开发至关重要,不能提前预测到可能发生的错误,不能提前采取恢复策略,可能导致较 ...

  9. Sql server2012连接Sql server 2008时出现的问题:已成功与服务器建立连接,但在登陆过程中发生错误。(provider:SSL Provider,error:0-接收到的消息异常,或格式不正确。)

    以前连接是正常的,就这两天连不上了.(没有耐心的直接看末尾解决办法) 错误消息如下: 1.尝试读取或写入受保护的内存.这通常指示其他内存已损坏.(System.Data) 2.已成功与服务器建立连接, ...

随机推荐

  1. bzoj3598 [Scoi2014]方伯伯的商场之旅

    数位dp,我们肯定枚举集合的位置,但是如果每次都重新dp的话会很麻烦,所以我们可以先钦定在最低位集合,dp出代价,然后再一步步找到正确的集合点,每次更改的代价也dp算就好了. #include < ...

  2. VIJOS-P1635 城市连接

    嘿嘿嘿,逆向spfa,貌似不难... #include <cstdio> #include <algorithm> #include <cmath> #includ ...

  3. js、jq事件绑定方式总结——以click事件为例

    一.JavaScript点击事件绑定方法 1.1 HTML onclick事件属性 <button onclick="clickMe(this)">click me&l ...

  4. ACM——八大输出方式总结

    个人做题总结,希望能够帮助到未来的学弟学妹们的学习! 永远爱你们的 ----新宝宝 1: 题目描述 Your task is to Calculate a + b. Too easy?! Of cou ...

  5. 谈谈 ANR 之 Service 超时

    1. 核心源码 关键类 路径(/frameworks/base/) ActiveServices.java services/core/java/com/android/server/am/Activ ...

  6. PostCSS 基本用法

    1.postcss相关网站 https://www.postcss.com.cn/ https://www.ibm.com/developerworks/cn/web/1604-postcss-css ...

  7. DataFrameNaFunctions无fill方法

    当我使用 spark2.1 ,为了填补 dataframe 里面的 null 值转换为 0 ,代码如下所示: dataframe.na.fill(0) 出现如下错误 Spark version 2.1 ...

  8. javascript入门篇(五)

    将日期转换为数字 全局方法 Number() 可将日期转换为数字 d = new Date(); Number(d)          // 返回 1404568027739 日期方法 getTime ...

  9. 对EF的封装

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.D ...

  10. Oracle 连接查询

    1.什么是连接查询?(B) 很多时候我们需要查询的数据并不是来源于同一张表,而是来源于多张表,而这种一个查询需要对多张表进行操作,就成为连接查询. 2.如何进行表的连接查询? 连接查询有两种方式:SQ ...