和其他服务器端语言相比,貌似node.js 对于异常捕捉确实非常困难.

首先你会想到try/catch ,但是在使用过程中我们会发现并没有真正将错误控制在try/catch 语句中.

为什么?

答案是这样的:

node.js 是异步IO执行,所以我们将try/catch 反正异步回调函数中,当出现一个异常的时候,我们try 拿到这个错误时应该错过了当前程序运行堆栈,

而在node.js原生的uncaughtException 处理事件却挂在 process 对象上,OMG,你可想而知,如果一个异常出现时,当前运行的 process 会直接挂掉,

导致错误永远不会走到 catch 语句.所以 try/catch 在异步回调中显得苍白无力,我们有什么办法控制这种异步回调的异常吗?

当然,我们下面来介绍一种比较有效的处理方法:

domain模块,这是node自带的一个模块,看名字确实很难联想到他是用来捕捉异常的,它能帮我们做一些try /catch无法做到的事情.

首先引用模块

var domain = require('domain');

如果你也使用Express框架,可以直接将domain 做成一个 Express 的中间件,这样所有的 request及response 中的异步错误都可以捕捉到.

app.configure(function () {app.use(function (req, res, next) {var reqDomain = domain.create();reqDomain.on('error', function (err) {  // 下面抛出的异常在这里被捕获,触发此事件console.log('捕获到错误');res.send(500, err.stack);           // 成功给用户返回了 500});reqDomain.run(next);});
});

上面这种写法是Express 的一个中间件写法, app.use(function(req,res,next){ .....}) 这是一个中间件,用来接收所有http请求,这里你可以捕获request 和 response 对象用来做一些过滤,逻辑判断等等,最后通过 next 来放行本次请求,那么这个中间件就完成了他的一次使命.

而我们为了让 domain 模块来接管所有的http请求中的异常,所以把它写成一个中间件是非常方便的.

然后我们在 process 上将未处理的异常捕捉一下,做到万无一失.

process.on('uncaughtException', function (err) {console.error("uncaughtException ERROR");if (typeof err === 'object') {if (err.message) {console.error('ERROR: ' + err.message)}if (err.stack) {console.error(err.stack);}} else {console.error('argument is not an object');}
});

//下面我们来定义几个路由,测试一下.

app.get('/', function (req, res) {levelDB.getData('test', function (err, v) {//这里我从levelDB 中读取一条数据,需要引入 levelDB 模块.err ? res.send({status: "fail"}) : res.send({status: "success", value: v});});
})

//我们再想办法让程序出现一个异步异常

app.get('/err', function (req, res) {//throw new Error('exception'); setTimeout(function () {throw new Error('exception'); // 抛出一个异步异常}, 1000);
})

//我们之所以想到用 setTimeout 就是想模拟一个异步的回调,如果你直接 throw new Error('exception');这样就不是异步了,直接会被 process 上的 uncaughtException 来接管.

通过上面定义的两个路由,我们来分别访问一下

这个路由我们从数据库读取了一条记录最后返回给客户端,中间没有出现任何异常.

这是我们模拟的一个异常已经被捕捉到,这是服务器端返回给客户端的一个500提示信息,这时我们再看一眼控制台,node 进程并没有挂掉.

每次 domian 捕获到错误后,我都在控制台输出了一行提示信息 "捕获到错误" 当前进程并没有因为异常而挂掉,这就是我们要的效果.

转载于:https://www.cnblogs.com/ysk123/p/9848612.html

node.js 使用domain模块捕获异步回调中的异常相关推荐

  1. Node.js express 之mongoose 从异步回调函数返回值,类似于同步

    http://my.oschina.net/antianlu/blog/187023 转载于:https://www.cnblogs.com/cylblogs/p/5192314.html

  2. 浅析 Node.js 的 vm 模块以及运行不信任代码

    为什么80%的码农都做不了架构师?>>>    在一些系统中,我们希望给用户提供插入自定义逻辑的能力,除了 RPC 和 REST 之外,运行客户提供的代码也是比较常用的方法,好处是可 ...

  3. Node.js 初识 fs 模块

    fs 模块是文件操作的封装,它提供了文件的读取.写入.更名.删除.遍历目录.链接等 Unix 文件系统操作.与其他模块不同的是,fs 模块中所有的操作都提供了 同步 和 异步 两个版本,比如读取文件内 ...

  4. php node 目录,node.js基于fs模块对系统文件及目录进行读写操作的方法详解

    本文主要介绍了node.js基于fs模块对系统文件及目录进行读写操作的方法,结合实例形式分析了nodejs使用fs模块针对文件与目录的读写.创建.删除等相关操作技巧,需要的朋友可以参考下. 如果要用这 ...

  5. Node.js web应用模块之forever

    javascript 一统江湖的势头越来越猛,越来越重的前端,不得不实施前后端分离,angular.js 成功把前端javascript抽象成了一个复杂的MVC框架,注意,它是一个框架,可不是普普通通 ...

  6. Node.js:海量数据大行其道的今天 node.js 在IO方面如何异步非阻塞

    以其高性能,异步IO著称,当然node.js 在 stream 上的异步也非常到位. 我们一般理解的异步请求是这样的: 同时处理多件件事件 A,B,C,D,E,F,G .... 如果用.net语言去处 ...

  7. 开场 Live,分享点干货——「深入了解 Node.js 包与模块机制」

    先放上 Live 地址: www.zhihu.com/lives/84274- 本次 Live 将深入剖析 Node.js 包与模块机制,包括且不限于解析 Node.js 源码.社区规范等.本人认为这 ...

  8. Node.js web应用模块之Supervisor

    在开发或调试Node.js应用程序的时候,当你修改js文件后,总是要按下CTRL+C终止程序,然后再重新启动,即使是修改一点小小的参数,也 总是要不断地重复这几个很烦人的操作.这是因为Node.js ...

  9. node.js 模块_如何创建Node JS可重用模块

    node.js 模块 In my previous post, we have discussed about "How to export and import a Node JS Mod ...

最新文章

  1. Redis初学16:主从复制
  2. ASP.NET MVC 1.0 NVelocityViewEngine
  3. .NET 数据访问中间件 HyperDAL v1.1 FAQ
  4. Read file, CSV read String
  5. tns 连接超时_ORA-12170:TNS:连接超时
  6. Altium designer中提示some net were not able to be matched问题解决办法
  7. HBase基础和伪分布式安装配置
  8. 在比特币世界中矿工的作用是什么
  9. spring入门笔记
  10. asterisk架构
  11. 易语言数据类型与c 对照,易语言利用自定义数据类型和数组. 制作键对值操作类/内存配置...
  12. 谈一谈我对于目前国人对于EXTJS的错误看法
  13. hdu 1520(树形dp)
  14. sprutcam 多机器人_Sprutcam工业机器人离线编程系统
  15. 【sv】 assign force区别
  16. 阿里云1核1G内存1M宽带支持多少IP访问量够用吗?
  17. 大S产女获张兰连续两天探望 大赞儿媳妇是骄傲
  18. Android HashTable
  19. 网络tracert详解
  20. 基于具体实验对脑部分区的具体调研

热门文章

  1. Java基础---继承
  2. 地推HTTP成长介绍
  3. 车辆撞人有全险但是是全责,车主不愿出钱垫付医药费,该怎么办?
  4. 你看到过哪些简短有内涵的一看就想发朋友圈的句子?
  5. 游戏主播们为什么早上不玩游戏?直播圈里还有哪些不成文的规定呢?
  6. 支付宝有50万存款,但欠30万房贷。是还房贷好,还是买基金好?
  7. 一亩地等于多少平方米?
  8. 下面两种送礼模式会让你的生意兴隆
  9. 维基链能成为下一个以太坊吗?
  10. power bi 创建空表_如何使用R在Power BI中创建地理地图