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编程起步(第五课)
Jan 10 Javascript
学习并汇集javascript匿名函数
Nov 25 Javascript
passwordStrength 基于jquery的密码强度检测代码使用介绍
Oct 08 Javascript
jquery拖动插件(jquery.drag)使用介绍
Jun 18 Javascript
D3.js 从P元素的创建开始(显示可加载数据)
Oct 30 Javascript
jquery+css实现绚丽的横向二级下拉菜单-附源码下载
Aug 23 Javascript
Bootstrap零基础入门教程(三)
Jul 18 Javascript
js实现四舍五入完全保留两位小数的方法
Aug 02 Javascript
详解Javascript中的原型OOP
Oct 12 Javascript
js 监控iframe URL的变化实例代码
Jul 12 Javascript
vue监听键盘事件的相关总结
Jan 29 Vue.js
使用Cargo工具高效创建Rust项目
Aug 14 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 删除记录实现代码
2009/03/12 PHP
用php制作简单分页(从数据库读取记录)的方法详解
2013/05/04 PHP
[原创]PHP获取数组表示的路径方法分析【数组转字符串】
2017/09/01 PHP
js列举css中所有图标的实现代码
2011/07/04 Javascript
Mac地址验证的javascript代码
2013/11/09 Javascript
css3元素简单的闪烁效果实现(html5 jquery)
2013/12/28 Javascript
jquery实现的淡入淡出下拉菜单效果
2015/08/25 Javascript
在Html中使用Requirejs进行模块化开发实例详解
2016/04/15 Javascript
浅析Nodejs npm常用命令
2016/06/14 NodeJs
使用Angular.js实现简单的购物车功能
2016/11/21 Javascript
Node.js+jade+mongodb+mongoose实现爬虫分离入库与生成静态文件的方法
2017/09/20 Javascript
JSON数据中存在单个转义字符“\”的处理方法
2018/07/11 Javascript
vue封装一个简单的div框选时间的组件的方法
2019/01/06 Javascript
javascript自定义日期比较函数用法示例
2019/07/22 Javascript
weui上传多图片,压缩,base64编码的示例代码
2020/06/22 Javascript
python提取内容关键词的方法
2015/03/16 Python
Python最基本的输入输出详解
2015/04/25 Python
Python实现统计英文单词个数及字符串分割代码
2015/05/28 Python
python+matplotlib绘制3D条形图实例代码
2018/01/17 Python
python基础教程项目四之新闻聚合
2018/04/02 Python
Python基于OpenCV库Adaboost实现人脸识别功能详解
2018/08/25 Python
python引入不同文件夹下的自定义模块方法
2018/10/27 Python
python脚本调用iftop 统计业务应用流量的思路详解
2019/10/11 Python
详解python方法之绑定方法与非绑定方法
2020/08/17 Python
python如何遍历指定路径下所有文件(按按照时间区间检索)
2020/09/14 Python
饿了么订餐官网:外卖、网上订餐
2019/06/28 全球购物
Java中实现多态的机制
2015/08/09 面试题
2013年员工自我评价范文
2013/12/27 职场文书
预备党员的自我评价
2014/03/12 职场文书
群众路线个人对照检查材料
2014/09/23 职场文书
融资合作协议书范本
2014/10/17 职场文书
党支部培养考察意见
2015/06/02 职场文书
健康教育主题班会
2015/08/14 职场文书
《语言的突破》读后感3篇
2019/12/12 职场文书
html+css实现分层金字塔的实例
2021/06/02 HTML / CSS
利用Python将list列表写入文件并读取的方法汇总
2022/03/25 Python