Koa 中的错误处理解析


Posted in Javascript onApril 09, 2019

不像 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 = `
  <b>${status}</b> ${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);

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

参考

Error Handling
ctx.throw

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JS去除字符串的空格增强版(可以去除中间的空格)
Aug 26 Javascript
js获取视频时长代码
Apr 10 Javascript
15个jquery常用方法、小技巧分享
Jan 13 Javascript
JavaScript实现图像模糊化的方法实例
Jan 15 Javascript
vue-cli + sass 的正确打开方式图文详解
Oct 27 Javascript
微信小程序如何获取openid及用户信息
Jan 26 Javascript
详解如何在vue项目中引入elementUI组件
Feb 11 Javascript
webpack中使用iconfont字体图标的方法
Feb 22 Javascript
详解Angularjs 自定义指令中的数据绑定
Jul 19 Javascript
详解React之key的使用和实践
Sep 29 Javascript
js array数组对象操作方法汇总
Mar 18 Javascript
详解小程序云开发攻略(解决最棘手的问题)
Sep 30 Javascript
简单说说如何使用vue-router插件的方法
Apr 08 #Javascript
利用Bootstrap Multiselect实现下拉框多选功能
Apr 08 #Javascript
纯javascript实现选择框的全选与反选功能
Apr 08 #Javascript
详解小程序如何避免多次点击,重复触发事件
Apr 08 #Javascript
「中高级前端面试」JavaScript手写代码无敌秘籍(推荐)
Apr 08 #Javascript
微信小程序BindTap快速连续点击目标页面跳转多次问题处理
Apr 08 #Javascript
vue.js实现会动的简历(包含底部导航功能,编辑功能)
Apr 08 #Javascript
You might like
Laravel 5 学习笔记
2015/03/06 PHP
PHP获取一年有几周以及每周开始日期和结束日期
2015/08/06 PHP
jquery预览图片实现鼠标放上去显示实际大小
2014/01/16 Javascript
JQuery记住用户名和密码的具体实现
2014/04/04 Javascript
手机端网页点击链接触发自动拨打或保存电话的示例代码
2014/08/15 Javascript
基于javascript实现动态时钟效果
2020/08/18 Javascript
AngularJS ng-repeat指令中使用track by子语句解决重复数据遍历错误问题
2017/01/21 Javascript
jQuery插件HighCharts绘制的2D堆柱状图效果示例【附demo源码下载】
2017/03/14 Javascript
Angularjs中数据绑定的实例详解
2017/08/25 Javascript
node实现基于token的身份验证
2018/04/09 Javascript
JS实现的简单折叠展开动画效果示例
2018/04/28 Javascript
微信小程序实现星级评分和展示
2018/07/05 Javascript
如何提升vue.js中大型数据的性能
2019/06/21 Javascript
Vue.js如何使用Socket.IO的示例代码
2019/09/05 Javascript
JavaScript实现捕获鼠标坐标
2020/04/12 Javascript
[03:40]DOTA2亚洲邀请赛小组赛第二日 赛事回顾
2015/01/31 DOTA
[57:28]2018DOTA2亚洲邀请赛 4.6 淘汰赛 TNC vs Liquid 第一场
2018/04/10 DOTA
Python时间戳与时间字符串互相转换实例代码
2013/11/28 Python
python 不以科学计数法输出的方法
2018/07/16 Python
python的pip安装以及使用教程
2018/09/18 Python
Python生成指定数量的优惠码实操内容
2019/06/18 Python
python3实现在二叉树中找出和为某一值的所有路径(推荐)
2019/12/26 Python
美国购买汽车零件网站:Buy Auto Parts
2018/04/02 全球购物
个性化皮包、小袋、生活配件:Mon Purse
2019/03/26 全球购物
捷克家具销售网站:SCONTO Nábytek
2020/01/02 全球购物
职业女性的职业规划
2014/03/04 职场文书
财务总监岗位职责
2014/03/07 职场文书
《美丽的丹顶鹤》教学反思
2014/04/22 职场文书
品德评语大全
2014/05/05 职场文书
交通事故委托书范本(2篇)
2014/09/21 职场文书
信用卡工资证明范本
2015/06/19 职场文书
小学三年级班主任工作经验交流材料
2015/11/02 职场文书
幼儿教师远程研修感悟
2015/11/18 职场文书
2016年综治和平安建设宣传月活动总结
2016/04/01 职场文书
2021-4-5课程——SQL Server查询【3】
2021/04/05 SQL Server
Redis基于Bitmap实现用户签到功能
2021/06/20 Redis