众所周知,异常捕获是保障服务健壮性常用的手段,node.js也自然支持这一特性。但node.js异步、基于消息的编程方式给异常捕获带来一些困难,请看下面的例子:
process.on('uncaughtException', function(e) {
    console.log("exception in uncaughtException:", e);
});
try {
    process.nextTick(function () {
        throw new Error("exception in nextTick callback");
    });
} catch (e) {
    console.log("exception in catch:", e);
}
输出:
exception in uncaughtException: [Error: exception in nextTick callback]
可见,try-catch不能捕获回调函数中的异常,也不能捕获事件响应函数中的异常。通常的解决办法是在这些函数中都加入try-catch,但副作用也很明显,一方面增加了代码复杂度和嵌套深度,降低了可读性和可维护性,另一方面v8对于try-catch中的代码优化作用会降低,即牺牲了性能。
node v0.8中新增了domain模块,大大简化异步开发中异常捕获的复杂度,引入domain的代码如下:
var domain = require('domain');
var d = domain.create();
d.on('error', function(e) {
    console.log("error in domain:", e);
});
d.run(function () {
    process.nextTick(function () {
        throw new Error("exception in nextTick callback");
    });
});
输出:
error in domain: { [Error: exception in nextTick callback]
  domain_thrown: true,
  domain: { members: [], _events: { error: [Function] } } }
以上只是一个简单的例子,domain的初衷在于解决异步io的异常处理,只要是注册在domain中event emitters、timer、callback函数,其回调函数中产生的"error"事件和exception都可以被domain捕获。
来看示例:
var domain = require('domain');
var events = require('events');
var d = domain.create();
d.on('error', function(e) {
    console.log("error in domain:", e);
});
var e;
d.run(function () {
    e = new events.EventEmitter();
});
e.on('msg', function () {
    throw new Error("exception in msg callback");
});
e.emit('error', new Error("error msg"));
e.emit('msg');
输出:
error in domain: { [Error: error msg]
  domain_emitter: 
   { domain: { members: [], _events: [Object] },
     _events: { msg: [Function] } },
  domain: { members: [], _events: { error: [Function] } },
  domain_thrown: false }
error in domain: { [Error: exception in msg callback]
  domain_thrown: true,
  domain: { members: [], _events: { error: [Function] } } }
注意不是EventEmitter所有成员函数中的exception都可以被自动捕获,如果成员函数不是在事件响应函数中执行,并且未跟domain绑定,就不会被domain捕获。
示例:
var domain = require('domain');
var events = require('events');
var d = domain.create();
d.on('error', function(e) {
    console.log("error in domain:", e);
});
var e;
d.run(function () {
    e = new events.EventEmitter();
});
e.f = function () {
    throw new Error("exception in member function");
};
e.f();
如果在domain.run()中执行,或跟domain绑定,是可以被捕获的:
d.run(function () {
    e.f();
});
domain还有其他接口,用于绑定对象、函数等,请参考官方文档:
http://nodejs.org/api/domain.html
转帖:http://blog.sina.com.cn/s/blog_70000469010134wr.html

domain: node.js的异常捕获利器相关推荐

  1. js的异常捕获try和catch语句

    js里也可以使用try{}catch(){}语句块.看范例: 1.js出错则问询是否继续查看 Code: <script type="text/javascript"> ...

  2. node.js 使用domain模块捕获异步回调中的异常

    和其他服务器端语言相比,貌似node.js 对于异常捕捉确实非常困难. 首先你会想到try/catch ,但是在使用过程中我们会发现并没有真正将错误控制在try/catch 语句中. 为什么? 答案是 ...

  3. Node.js 在微医的应用场景及实践

    我是来自微医集团消费事业群的前端工程师高翔,这篇文章整理自我在<第一届缤纷前端技术沙龙>的主题分享<Node.js 在医疗行业的应用>,介绍了 Node.js 在微医的发展历程 ...

  4. 【特别推荐】Node.js 中文学习资料和教程导航

    这篇文章来自 Github 上的一位开发者收集整理的 Node.js 中文学习资料和教程导航.Node 是一个服务器端 JavaScript 解释器,它将改变服务器应该如何工作的概念,它的目标是帮助程 ...

  5. 如何将命令行参数传递给Node.js程序?

    我有一个用Node.js编写的Web服务器,我想使用一个特定的文件夹启动. 我不确定如何在JavaScript中访问参数. 我正在像这样运行节点: $ node server.js folder 这是 ...

  6. Node.js异常捕获处理

    文章目录 Node.js异常特点 异常的捕获处理 同步异常 异步异常 callback event Promise Async/Await uncaughtException异常 Node.js异常特 ...

  7. Node.js Domain 模块

    Node.js 工具模块 Node.js Domain(域) 简化异步代码的异常处理,可以捕捉处理try catch无法捕捉的异常.引入 Domain 模块 语法格式如下: var domain = ...

  8. atitit.js浏览器环境下的全局异常捕获

    atitit.js浏览器环境下的全局异常捕获 window.onerror = function(errorMessage, scriptURI, lineNumber) { var s= JSON. ...

  9. js监听多个事件_JavaScript中的事件与异常捕获解析

    这篇文章主要给大家介绍了关于JavaScript中事件与异常捕获的相关资料,文中通过示例代码介绍的非常详细,写的十分的全面细致,具有一定的参考价值,对此有需要的朋友可以参考学习下.如有不足之处,欢迎批 ...

最新文章

  1. 太赞了!NumPy 手写所有主流 ML 模型,由普林斯顿博士后 David Bourgin打造的史上最强机器学习基石项目!...
  2. linux修改系统时间为北京时间(CentOS)
  3. 通过AAA服务器使用XML文件为远程接入SSL ***认证授权
  4. 1.8 ionic3入门——测滑菜单(side menu)中的界面跳转
  5. 【Linux】一步一步学Linux——readonly命令(219)
  6. 基于互联网大数据的管理创新
  7. Java使用Apache CXF开发Web Service
  8. 计组之存储系统:4、双口RAM和多模块存储器(存取周期、双端口RAM、多体并行存储器、存储体)
  9. Python int() 函数
  10. 他,用了14年,从初代豆瓣工程师到AI公司CTO,创业心一直未变
  11. 源码:winamp播放器 C++
  12. 计算机属性资源管理器已停止工作,windows资源管理器已停止工作,教您windows资源管理器已停止工作如何解决...
  13. 关于Gitlab恼人的Git无权限访问问题解决
  14. 初中作文计算机想象作文,初中想象作文600
  15. ThinkPHP实现定时执行任务的两种方法
  16. 僵尸网络新世界:摄像头的背叛和战争
  17. :hover的几种选择用法
  18. MySQL数据导出与导入
  19. C语言自动识别文本编码
  20. 1995年的一次访谈中,乔布斯谈到处于垄断地位的科技公司因为营销人员掌握了话语权,不再注重产品研发而衰败

热门文章

  1. 【蓝桥杯2018JavaB】螺旋折线
  2. Ultraman 奥特曼名字
  3. Result Maps collection already contains value for问题
  4. Sui主网升级至V1.2.0版本
  5. 面向对象--02面向对象的三个基本特征
  6. Apollo 配置中心源码分析
  7. Android12修改关机菜单按键触发方式
  8. 微电网与电动车蓄电池优化(Matlab代码实现)
  9. Jersey框架:统一异常处理
  10. 企业微信获取用户信息响应40029(微信小程序与公众号出现类似问题应该是同样的原因)