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 相关文章推荐
Jquery Validation插件防止重复提交表单的解决方法
Mar 05 Javascript
枚举的实现求得1-1000所有出现1的数字并计算出现1的个数
Sep 10 Javascript
使用JS或jQuery模拟鼠标点击a标签事件代码
Mar 10 Javascript
JavaScript实现三阶幻方算法谜题解答
Dec 29 Javascript
浅谈angular懒加载的一些坑
Aug 20 Javascript
JavaScript实现实时更新系统时间的实例代码
Apr 04 Javascript
通过js修改input、select默认字体颜色
Apr 19 Javascript
Jquery获取radio选中的值
May 05 jQuery
bootstrap table实现双击可编辑、添加、删除行功能
Sep 27 Javascript
解决vue打包之后静态资源图片失效的问题
Feb 21 Javascript
vue中axios的封装问题(简易版拦截,get,post)
Jun 15 Javascript
js实现上传按钮并显示缩略图小轮子
May 04 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
终于听上了直流胆调频
2021/03/02 无线电
在openSUSE42.1下编译安装PHP7 的方法
2015/12/24 PHP
PHP编程 SSO详细介绍及简单实例
2017/01/13 PHP
详细解读php的命名空间(一)
2018/02/21 PHP
基于jquery的动态创建表格的插件
2011/04/05 Javascript
国外大牛IE版本检测!现在IE都到9了,IE检测代码
2012/01/04 Javascript
JavaScript极简入门教程(一):基础篇
2014/10/25 Javascript
如何编写高质量JS代码
2014/12/28 Javascript
JavaScript中5种调用函数的方法
2015/03/12 Javascript
jquery代码实现多选、不同分享功能
2015/07/31 Javascript
js实现模糊匹配功能
2017/02/15 Javascript
javascript兼容性(实例讲解)
2017/08/15 Javascript
Vue.js与 ASP.NET Core 服务端渲染功能整合
2017/11/16 Javascript
Angular4 ElementRef的应用
2018/02/26 Javascript
WebPack配置vue多页面的技巧
2018/05/15 Javascript
JS实现用特殊符号替换字符串的中间部分区域的实例代码
2018/07/24 Javascript
详解Vue中watch的详细用法
2018/11/28 Javascript
小程序实现录音功能
2020/09/22 Javascript
剖析Python的Tornado框架中session支持的实现代码
2015/08/21 Python
Python和JavaScript间代码转换的4个工具
2016/02/22 Python
Python+微信接口实现运维报警
2016/08/27 Python
Python对文件和目录进行操作的方法(file对象/os/os.path/shutil 模块)
2017/05/08 Python
python3中获取文件当前绝对路径的两种方法
2018/04/26 Python
Django 多环境配置详解
2019/05/14 Python
Django 实现外键去除自动添加的后缀‘_id’
2019/11/15 Python
Python远程开发环境部署与调试过程图解
2019/12/09 Python
k-means 聚类算法与Python实现代码
2020/06/01 Python
使用Python FastAPI构建Web服务的实现
2020/06/08 Python
使用Html5 Stream开发实时监控系统
2020/06/02 HTML / CSS
大学军训自我鉴定
2013/12/15 职场文书
酒后驾车标语
2014/06/30 职场文书
2014年物流工作总结
2014/11/25 职场文书
2015年党建工作总结
2015/03/30 职场文书
恰同学少年观后感
2015/06/08 职场文书
2019奶茶店创业计划书范本,值得你借鉴
2019/08/14 职场文书
python垃圾回收机制原理分析
2022/04/13 Python