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 相关文章推荐
multiSteps 基于Jquery的多步骤滑动切换插件
Jul 22 Javascript
改进版通过Json对象实现深复制的方法
Oct 24 Javascript
jquery禁用右键单击功能屏蔽F5刷新
Mar 17 Javascript
js实现局部页面打印预览原理及示例代码
Jul 03 Javascript
jQuery构造函数init参数分析
May 13 Javascript
基于JavaScript如何实现ajax调用后台定义的方法
Dec 29 Javascript
原生JS+Canvas实现五子棋游戏实例
Jun 19 Javascript
深入浅析Vue.js中 computed和methods不同机制
Mar 22 Javascript
vue-cli初始化项目中使用less的方法
Aug 09 Javascript
从vue源码解析Vue.set()和this.$set()
Aug 30 Javascript
Node.js EventEmmitter事件监听器用法实例分析
Jan 07 Javascript
微信小程序实现列表的横向滑动方式
Jul 15 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
php的控制语句
2006/10/09 PHP
PHP定时自动生成静态HTML的实现代码
2010/06/20 PHP
php遍历文件夹下的所有文件和子文件夹示例
2014/03/20 PHP
php中删除、清空session的方式总结
2015/10/09 PHP
PHP面向对象详解(三)
2015/12/07 PHP
php实现用户注册密码的crypt加密
2017/06/08 PHP
实例讲解PHP页面静态化
2018/02/05 PHP
javascript级联下拉列表实例代码(自写)
2013/05/10 Javascript
在表单提交前进行验证的几种方式整理
2013/07/31 Javascript
js 调用百度地图api并在地图上进行打点添加标注
2014/05/13 Javascript
js通过location.search来获取页面传来的参数
2014/09/11 Javascript
Vue.js每天必学之指令系统与自定义指令
2016/09/07 Javascript
JS正则表达式之非捕获分组用法实例分析
2016/12/28 Javascript
详解js几个绕不开的事件兼容写法
2017/08/30 Javascript
React Native 截屏组件的示例代码
2017/12/06 Javascript
nodejs基础之buffer缓冲区用法分析
2018/12/26 NodeJs
浅谈VUE防抖与节流的最佳解决方案(函数式组件)
2019/05/22 Javascript
layui上传图片到服务器的非项目目录下的方法
2019/09/26 Javascript
vue excel上传预览和table内容下载到excel文件中
2019/12/10 Javascript
vue实现购物车的监听
2020/04/20 Javascript
解决angular 使用原生拖拽页面卡顿及表单控件输入延迟问题
2020/04/21 Javascript
webstorm建立vue-cli脚手架的傻瓜式教程
2020/09/22 Javascript
[02:56]DOTA2上海特锦赛小组赛解说FreeAgain采访花絮
2016/02/27 DOTA
[48:05]2018DOTA2亚洲邀请赛 3.31 小组赛 B组 VGJ.T vs VP
2018/03/31 DOTA
Python交换变量
2008/09/06 Python
python简单实现旋转图片的方法
2015/05/30 Python
django数据库migrate失败的解决方法解析
2018/02/08 Python
对Python3中列表乘以某一个数的示例详解
2019/07/20 Python
python匿名函数用法实例分析
2019/08/03 Python
德国最大的网上足球商店:11teamsports
2019/09/11 全球购物
区域销售经理职责
2013/12/22 职场文书
诚信贷款承诺书
2014/05/30 职场文书
乡镇党员干部群众路线对照检查材料思想汇报
2014/09/28 职场文书
财务审计整改报告
2014/11/06 职场文书
教师个人教学总结
2015/02/11 职场文书
Node.js实现爬取网站图片的示例代码
2022/04/04 NodeJs