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 相关文章推荐
用javascript动态调整iframe高度的代码
Apr 10 Javascript
用js实现控制内容的向上向下滚动效果
Jun 26 Javascript
js的alert弹出框出现乱码解决方案
Sep 02 Javascript
JS根据年月获得当月天数的实现代码
Jul 03 Javascript
JS使用cookie设置样式的方法
Jun 30 Javascript
全面理解闭包机制
Jul 11 Javascript
JavaScript运动框架 解决防抖动问题、悬浮对联(二)
May 17 Javascript
详解基于webpack搭建react运行环境
Jun 01 Javascript
史上最全JavaScript数组去重的十种方法(推荐)
Aug 17 Javascript
arcgis for js栅格图层叠加(Raster Layer)问题
Nov 22 Javascript
利用Javascript实现一套自定义事件机制
Dec 14 Javascript
vue-cli基础配置及webpack配置修改的完整步骤
Oct 20 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
DSP接收机前端设想
2021/03/02 无线电
Breeze 文章管理系统 v1.0.0正式发布
2006/12/14 PHP
PHP 遍历文件实现代码
2011/05/04 PHP
php获取服务器信息的实现代码
2013/02/04 PHP
php+redis实现消息队列功能示例
2019/09/19 PHP
通过实例解析PHP数据类型转换方法
2020/07/11 PHP
jQuery使用手册之 事件处理
2007/03/24 Javascript
将CKfinder整合进CKEditor3.0的新方法
2010/01/10 Javascript
javascript中window.event事件用法详解
2012/12/11 Javascript
原生js拖拽(第一课 未兼容)拖拽思路
2013/03/29 Javascript
两个数组去重的JS代码
2013/12/04 Javascript
jquery中map函数与each函数的区别实例介绍
2014/06/23 Javascript
jQuery团购倒计时特效实现方法
2015/05/07 Javascript
JavaScript基本语法讲解
2015/06/03 Javascript
javascript中setInterval的用法
2015/07/19 Javascript
JS获取时间的相关函数及时间戳与时间日期之间的转换
2016/02/04 Javascript
uploader秒传图片到服务器完整代码
2017/04/22 Javascript
javascript回调函数的概念理解与用法分析
2017/05/27 Javascript
基于es6三点运算符的使用方法(实例讲解)
2017/10/12 Javascript
微信小程序scroll-view横向滑动嵌套for循环的示例代码
2018/09/20 Javascript
JavaScript实现的开关灯泡点击切换特效示例
2019/07/08 Javascript
vue组件系列之TagsInput详解
2020/05/14 Javascript
详解Node.js使用token进行认证的简单示例
2020/05/25 Javascript
详解JavaScript中的this指向问题
2021/02/05 Javascript
[58:37]Serenity vs Fnatic 2018国际邀请赛淘汰赛BO1 8.21
2018/08/22 DOTA
[02:02]特效爆炸!DOTA2珍宝之瓶待你开启
2018/08/21 DOTA
python中logging库的使用总结
2017/10/18 Python
使用python去除图片白色像素的实例
2019/12/12 Python
html2 canvas生成清晰的图片实现打印功能
2019/09/23 HTML / CSS
美国知名珠宝首饰品牌:Gemvara
2017/10/06 全球购物
英国布鲁姆精品店:Bloom Boutique
2018/03/01 全球购物
Raffaello Network德国:意大利拉斐尔时尚购物网
2019/05/01 全球购物
一年级评语大全
2014/04/23 职场文书
2017公司年会主持人开幕词
2016/03/04 职场文书
python实现监听键盘
2021/04/26 Python
【海涛教你打DOTA】剑圣第一人称视角解说
2022/04/01 DOTA