Javascript 即使处理了未捕获的异常,Node.js程序也会退出

Javascript 即使处理了未捕获的异常,Node.js程序也会退出,javascript,node.js,exception,Javascript,Node.js,Exception,我编写了以下代码来处理我的应用程序中的未捕获异常(我知道这是一个相当幼稚的错误处理方法,该代码只是为了回答这个问题): 当我运行代码时,我得到了以下输出: starting... Handling exception 出于某种原因,即使处理了异常,程序也没有运行最后一行代码就退出了。 当我使用try catch块包装对f()的调用时,最后一行被执行,单词“Done”被打印到屏幕上 我的问题是: 这是预期的行为吗 为什么这两种机制(侦听事件和使用try-catch)之间存在差异 这正是您所期望的

我编写了以下代码来处理我的应用程序中的未捕获异常(我知道这是一个相当幼稚的错误处理方法,该代码只是为了回答这个问题):

当我运行代码时,我得到了以下输出:

starting...
Handling exception
出于某种原因,即使处理了异常,程序也没有运行最后一行代码就退出了。 当我使用
try catch
块包装对
f()
的调用时,最后一行被执行,单词“Done”被打印到屏幕上

我的问题是:

  • 这是预期的行为吗
  • 为什么这两种机制(侦听事件和使用try-catch)之间存在差异

  • 这正是您所期望的行为,未捕获的异常将停止脚本的正常执行,因此永远不会进行“Done”日志调用

    您可以在Node.js文档中看到一个更好的例子:

    正如文件所说:

    Note that 'uncaughtException' is a crude mechanism for exception handling intended to be used only as a last resort. uncaughtException处理程序的作用正是:捕获任何未由try处理的异常。。。在您自己的代码中捕获处理程序。主要目的应该是记录错误,以便以后可以修复它们

    在任何情况下,最好将脚本包装在一个重启机制中,比如永久或在这种情况下旋转一个新的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');
    
    // 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');
    
    脚本2:

    // 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');
    
    // 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');
    

    您可以在第二个脚本中看到,我们直接退出,因为我们没有未捕获的异常处理程序。

    我阅读了文档,但我不明白一件基本的事情:为什么它会声明:“未处理的异常本质上意味着应用程序处于未定义状态。尝试在没有从异常中正确恢复的情况下恢复应用程序代码可能会导致其他不可预见和不可预测的问题。"? 如果程序仍然退出,这句话的意义是什么?但是如果其他操作正在运行、承诺、计时器等,它将不会退出。在您的情况下,应用程序退出的原因是在任何情况下都没有更多的工作要做。将超时设置为10秒或1分钟将使脚本保持活动状态。请参阅我的脚本1和脚本2示例!我希望程序退出,但在它运行“console.log('Done');”之后行,但此行没有运行console.log(“完成”)行仍然不会运行,因为在此之前程序执行被中断。但任何其他任务、计时器、承诺等仍在运行。如果希望确保此行运行,则必须使用异常处理程序。使用try catch可以创建特定于每个函数的错误处理代码。添加uncaughtException处理程序是一个全局故障保护,它将捕获任何其他处理程序未捕获的任何异常。正如文档中所说,由于程序将处于未知状态,因此最好在此时退出。只想链接到这篇关于处理节点中未捕获异常的优秀博文。