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 相关文章推荐
超强的IE背景图片闪烁(抖动)的解决办法
Sep 09 Javascript
document.onreadystatechange事件的用法分析
Oct 17 Javascript
js操纵跨frame的三级联动select下拉选项实例介绍
May 19 Javascript
使用JavaScript刷新网页的方法
Jun 04 Javascript
使用angularjs创建简单表格
Jan 21 Javascript
微信小程序 参数传递详解
Oct 24 Javascript
使用D3.js+Vue实现一个简单的柱形图
Aug 05 Javascript
微信小程序实现同时上传多张图片
Feb 03 Javascript
js实现经典贪吃蛇小游戏
Mar 19 Javascript
JavaScript监听一个DOM元素大小变化
Apr 26 Javascript
利用H5api实现时钟的绘制(javascript)
Sep 13 Javascript
javascript函数式编程基础
Sep 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
Laravel自动生成UUID,从建表到使用详解
2019/10/24 PHP
出现“不能执行已释放的Script代码”错误的原因及解决办法
2007/08/29 Javascript
JS中字符问题(二进制/十进制/十六进制及ASCII码之间的转换)
2008/11/03 Javascript
动态的创建一个元素createElement及删除一个元素
2014/01/24 Javascript
AngularJS入门教程(一):静态模板
2014/12/06 Javascript
jQuery 获取屏幕高度、宽度的简单实现案例
2016/05/17 Javascript
jQuery基于ID调用指定iframe页面内的方法
2016/07/06 Javascript
Bootstrap table的使用方法
2016/11/02 Javascript
Bootstrap Modal遮罩弹出层代码分享
2016/11/21 Javascript
浅谈Javascript事件对象
2017/02/05 Javascript
jQuery实现的页面遮罩层功能示例【测试可用】
2017/10/14 jQuery
Webpack的dll功能使用
2018/06/28 Javascript
浅析Proxy可以优化vue的数据监听机制问题及实现思路
2018/11/29 Javascript
深入理解nodejs搭建静态服务器(实现命令行)
2019/02/05 NodeJs
Vuejs学习笔记之使用指令v-model完成表单的数据双向绑定
2019/04/29 Javascript
Vue 动态路由的实现及 Springsecurity 按钮级别的权限控制
2019/09/05 Javascript
在vue中使用Echarts画曲线图的示例
2020/10/03 Javascript
Python中使用copy模块实现列表(list)拷贝
2015/04/14 Python
Python简单删除目录下文件以及文件夹的方法
2015/05/27 Python
[原创]使用豆瓣提供的国内pypi源
2017/07/02 Python
python使用正则表达式替换匹配成功的组并输出替换的次数
2017/11/22 Python
python flask几分钟实现web服务的例子
2019/07/26 Python
python全局变量引用与修改过程解析
2020/01/07 Python
Python参数传递对象的引用原理解析
2020/05/22 Python
pyMySQL SQL语句传参问题,单个参数或多个参数说明
2020/06/06 Python
Python常用模块函数代码汇总解析
2020/08/31 Python
python 绘制国旗的示例
2020/09/27 Python
python之openpyxl模块的安装和基本用法(excel管理)
2021/02/03 Python
详解Html5 监听拦截Android返回键方法
2018/04/18 HTML / CSS
Qoo10台湾站:亚洲领先的在线市场
2018/05/15 全球购物
美国在线购物频道:Shop LC
2019/04/21 全球购物
国际贸易专业自荐信
2014/06/10 职场文书
酒店采购员岗位职责
2015/04/03 职场文书
诚信考试主题班会
2015/08/17 职场文书
社区志愿者服务心得体会
2016/01/22 职场文书
阿里云服务器Ubuntu 20.04上安装Odoo 15
2022/05/20 Servers