如果是从回调中抛出异常的,则由那个调用了回调的人负责捕获该异常。但如果异常从未被捕获,又会怎么样?这时,不同的JavaScript环境有着不同的游戏规则…… 1. 在浏览器环境中 现代浏览器会在开发人员控制台显示那些未捕获的异常,接着返回事件队列。要想修改这种行为,可以给window.onerror附加一个处理器。如果windows.onerror处理器返回true,则能阻止浏览器的默认错误处理行为。 window.onerror = function(err) { return true; //彻底忽略所有错误 }; 在成品应用中,会考虑某种JavaScript错误处理服务,譬如Errorception 。Errorception提供了一个现成的windows.onerror处理器,它向应用服务器报告所有未捕获的异常,接着应用服务器发送消息通知我们。 2. 在Node.js环境中 在Node环境中,window.onerror的类似物就是process对象的uncaughtException事件。正常情况下,Node应用会因未捕获的异常而立即退出。但只要至少还有一个uncaughtException事件处理器,Node应用就会直接返回事件队列。 process.on('uncaughtException', function(err) { console.error(err); //避免了关停的命运! }); 但是,自Node 0.8.4起,uncaughtException事件就被废弃了。据其文档 所言, 对异常处理而言,uncaughtException是一种非常粗暴的机制,它在将来可能会被放弃…… 请勿使用uncaughtException,而应使用Domain对象。 Domain对象又是什么?你可能会这样问。Domain对象是事件化对象(第2章会详细讨论),它将throw转化为'error'事件。下面是一个例子。 EventModel/domainThrow.js var myDomain = require('domain').create(); myDomain.run(function() { setTimeout(function() { throw new Error('Listen to me!') }, 50); }); myDomain.on('error', function(err) { console.log('Error ignored!'); }); 源于延时事件的throw只是简单地触发了Domain对象的错误处理器。 Error ignored! 很奇妙,是不是?Domain对象让throw语句生动了很多。遗憾的是,仅在Node 0.8+环境中才能使用Domain对象;在我写作本书时,Domain对象仍被视作试验性的特性。更多信息请参阅Node文档。 不管在浏览器端还是服务器端,全局的异常处理器都应被视作最后一根救命稻草。请仅在调试时才使用它。