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 delete操作符应用实例
Jan 13 Javascript
bootstrap fileinput完整实例分享
Nov 08 Javascript
详解原生js实现offset方法
Jun 15 Javascript
jQuery扩展_动力节点Java学院整理
Jul 05 jQuery
JavaScript实现body内任意节点的自定义属性功能示例
Sep 18 Javascript
Vue实现导出excel表格功能
Mar 30 Javascript
Vue实现PopupWindow组件详解
Apr 28 Javascript
JavaScript实现的简单加密解密操作示例
Jun 01 Javascript
vue.js中toast用法及使用toast弹框的实例代码
Aug 27 Javascript
在Vue项目中,防止页面被缩放和放大示例
Oct 28 Javascript
Js实现复选框的全选、全不选反选功能代码实例
Feb 28 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
FleaPHP的安全设置方法
2008/09/15 PHP
php 生成WML页面方法详解
2009/08/09 PHP
php阳历转农历优化版
2016/08/08 PHP
JavaScript打开word文档的实现代码(c#)
2012/04/16 Javascript
javascript禁制后退键(Backspace)实例代码
2013/11/15 Javascript
通过onmouseover选项卡实现img图片的变化
2014/02/12 Javascript
js二维数组定义和初始化的三种方法总结
2014/03/03 Javascript
IE浏览器IFrame对象内存不释放问题解决方法
2014/08/22 Javascript
通过js为元素添加多项样式,浏览器全兼容写法
2014/08/30 Javascript
JavaScript中的变量作用域介绍
2014/12/31 Javascript
JavaScript检查弹出窗口是否被阻拦的方法技巧
2015/03/13 Javascript
JavaScript实现随机替换图片的方法
2015/04/16 Javascript
js实现黑色简易的滑动门网页tab选项卡效果
2015/08/31 Javascript
jquery原理以及学习技巧介绍
2015/11/11 Javascript
JS基于面向对象实现的拖拽功能示例
2016/12/20 Javascript
微信小程序 radio单选框组件详解及实例代码
2017/01/10 Javascript
es7学习教程之fetch解决异步嵌套问题的方法示例
2017/07/21 Javascript
Vue2 模板template的四种写法总结
2018/02/23 Javascript
webpack打包js的方法
2018/03/12 Javascript
vue框架下部署上线后刷新报404问题的解决方案(推荐)
2019/04/03 Javascript
JavaScript使用百度ECharts插件绘制饼图操作示例
2019/11/26 Javascript
jQuery实现颜色打字机的完整代码
2020/03/19 jQuery
Tensorflow 合并通道及加载子模型的方法
2018/07/26 Python
Python线性拟合实现函数与用法示例
2018/12/13 Python
对Python中DataFrame选择某列值为XX的行实例详解
2019/01/29 Python
python面试题之列表声明实例分析
2019/07/08 Python
Python开发之pip安装及使用方法详解
2020/02/21 Python
从python读取sql的实例方法
2020/07/21 Python
中医临床专业自我鉴定范文
2014/01/15 职场文书
会计电算化大学生职业规划书
2014/02/05 职场文书
2014年为民办实事工作总结
2014/12/20 职场文书
幼儿园三八妇女节活动总结
2015/02/06 职场文书
求职信内容一般写什么?
2015/03/20 职场文书
中国汉字听写大会观后感
2015/06/02 职场文书
MySQL 字符集 character
2022/05/04 MySQL
java开发双人五子棋游戏
2022/05/06 Java/Android