javascript - 即使处理了未捕获的异常,Node.js 程序也会退出
问题描述
我编写了以下代码来处理我的应用程序中的未捕获异常(我知道这是一种相当幼稚的错误处理方法,该代码仅用于问题的目的):
process.on("uncaughtException", err => {
console.log('Handling exception');
});
console.log('starting...');
function f() {
throw(new Error('Error'));
}
f();
console.log('Done');
当我运行代码时,我得到以下输出:
starting...
Handling exception
由于某种原因,即使处理了异常,程序也没有运行最后一行代码就退出了。f()
当我用一个块包裹调用时try-catch
,最后一行被执行并且“完成”这个词被打印到屏幕上。
我的问题是:
- 这是预期的行为吗?
- 为什么这两种机制(监听事件和使用try-catch)有区别?
解决方案
这正是您所期望的行为,未捕获的异常将停止脚本的正常执行,因此永远不会进行“完成”日志调用。
您可以在此处的 Node.js 文档中看到更好的示例:https ://nodejs.org/api/process.html#process_event_uncaughtexception
正如文档所说:
请注意,“uncaughtException”是一种粗略的异常处理机制,仅用作最后的手段。
他们明确记录“这不会运行”,因为这是预期的行为。
如果您确实捕获了异常,脚本执行将不会停止,并且日志调用将照常进行。
process.on('uncaughtException', (err, origin) => {
fs.writeSync(
process.stderr.fd,
`Caught exception: ${err}\n` +
`Exception origin: ${origin}`
);
});
setTimeout(() => {
console.log('This will still run.');
}, 500);
// Intentionally cause an exception, but don't catch it.
nonexistentFunc();
console.log('This will not run.');
uncaughtException 处理程序正是为了做到这一点:在您自己的代码中捕获任何未由 try ... catch 处理程序处理的异常。主要目的应该是记录错误,以便以后可以修复它们。
在任何情况下,最好将脚本包装在像 Forever 这样的重启机制中,或者如果发生这种情况,只需启动一个新的 Docker 容器。
现在在您的情况下没有真正的区别,因为脚本无论如何都会立即退出。但是看看这两个脚本之间的区别:
脚本 1:
// Keep the script alive by setting a timeout. Because we have an exception handler in place we can keep doing stuff!
let interval = setInterval(() => console.log("I'm still alive!!"), 500);
setTimeout(() => { clearInterval(interval); console.log("Timeout done...")} , 5000);
process.on("uncaughtException", err => {
console.log('Handling exception');
});
console.log('starting...');
function f() {
throw(new Error('Error'));
}
f();
console.log('Done');
脚本 2:
// Keep the script alive by setting a timeout. Since there is no exception handler set the script will terminate immediately in any case.
let interval = setInterval(() => console.log("I'm still alive!!"), 500);
setTimeout(() => { clearInterval(interval); console.log("Timeout done...")} , 5000);
console.log('starting...');
function f() {
throw(new Error('Error'));
}
f();
console.log('Done');
您可以在第二个脚本中看到我们直接退出,因为我们没有未捕获的异常处理程序。
推荐阅读
- node.js - npm start 不运行反应项目
- c# - 在框架“netcoreapp2.0”和 RID“debian.8-x64”上使用 PostSharp 构建错误
- python - 对python气泡进行排序
- android - 为什么android.arch.navigation会导致程序类型已经存在:android.support.v4.os.ResultReceiver$1?
- shell - 编写一个 shell 脚本来找到一个二项式系数 c(n,k)
- google-chrome-extension - chrome.tabs.executeScript 不可靠
- angular - 未创建外部模块的服务实例
- git - 用任何东西删除 git 分支,而不是名称
- python - 在使用 Python 源代码时编辑它们的安全且简单的工作流程是什么?
- testing - TestNG 将重试方法报告为单独的测试运行