是否可以在Node.js中捕获所有当前未捕获的异常处理程序?

是否可以在Node.js中捕获所有当前未捕获的异常处理程序?,node.js,Node.js,我正在制作一个Node.js异常报告程序(NPM包),我需要它与其他异常报告程序(如Raven)一起工作。Raven和其他一些异常处理程序的问题是,它在收到未捕获的异常后退出进程。这使得我的异常报告程序无法通过http发送异常报告 我想知道是否有可能: 获取所有当前正在运行的未捕获异常处理程序 获取所有即将出现的未捕获异常处理程序 所以基本上,我想做的是围绕这些坏男孩,确保我的异常报告员首先运行。例如: uncaughtexception=>myexceptionreporter=>Raven=

我正在制作一个Node.js异常报告程序(NPM包),我需要它与其他异常报告程序(如Raven)一起工作。Raven和其他一些异常处理程序的问题是,它在收到未捕获的异常后退出进程。这使得我的异常报告程序无法通过http发送异常报告

我想知道是否有可能:

  • 获取所有当前正在运行的未捕获异常处理程序
  • 获取所有即将出现的未捕获异常处理程序
  • 所以基本上,我想做的是围绕这些坏男孩,确保我的异常报告员首先运行。例如:

    uncaughtexception=>myexceptionreporter=>Raven=>process.exit(1)

    uncaughtexception=>myexceptionreporter=>项目自己的exceptionreporter=>它认为合适的任何东西

    我还需要确保,如果没有其他例外,我们应该退出流程:


    uncaughtexception=>myexceptionreporter=>nothing=>process.exit(1)

    您可以使用进程“uncaughtException”和“unhandledRejection”事件

    还要记住,在“uncaughtException”之后恢复正常操作是不安全的,因为系统已损坏:

    例如:

    process
      .on('unhandledRejection', (reason, p) => {
        console.error(reason, 'Unhandled Rejection at Promise', p);
      })
      .on('uncaughtException', err => {
        console.error(err, 'Uncaught Exception thrown');
        process.exit(1);
      });
    

    您可以使用进程“uncaughtException”和“unhandledRejection”事件

    还要记住,在“uncaughtException”之后恢复正常操作是不安全的,因为系统已损坏:

    例如:

    process
      .on('unhandledRejection', (reason, p) => {
        console.error(reason, 'Unhandled Rejection at Promise', p);
      })
      .on('uncaughtException', err => {
        console.error(err, 'Uncaught Exception thrown');
        process.exit(1);
      });
    

    进程
    是一个
    事件发射器
    。就是这样

    process.on('uncaughtException, ...) 
    
    工作

    您可以访问流程对象的
    EventEmitter
    部分,找到为
    uncaughtExceptions
    注册的所有处理程序,并处理一些事情,使您的处理程序排在第一位。这有点像黑客,但它是可以做到的。您甚至可以在process对象上使用monkey patch
    .on()
    ,以便捕获该事件的任何后续侦听器

    这里有一个函数,它将删除
    未处理的弹出
    的所有现有侦听器,然后添加回其他侦听器,以确保您的侦听器是第一个被调用的侦听器

    function addListenerFirstInLine(emitter, eventName, listener) {
        // get existing listeners for the target event
        const listeners = emitter.listeners(eventName);
    
        // remove then all
        emitter.removeAllListeners(eventName);
    
        // add new listener first in line
        emitter.on(eventName, listener);
    
        // put back prior listeners after ours
        for (const fn of listeners) {
            emitter.on(eventName, fn);
        }
    }
    
    然后,您可以将其用于以下应用程序:

    addListenerFirstInLine(process, "uncaughtException", myListener)
    

    进程
    是一个
    事件发射器
    。就是这样

    process.on('uncaughtException, ...) 
    
    工作

    您可以访问流程对象的
    EventEmitter
    部分,找到为
    uncaughtExceptions
    注册的所有处理程序,并处理一些事情,使您的处理程序排在第一位。这有点像黑客,但它是可以做到的。您甚至可以在process对象上使用monkey patch
    .on()
    ,以便捕获该事件的任何后续侦听器

    这里有一个函数,它将删除
    未处理的弹出
    的所有现有侦听器,然后添加回其他侦听器,以确保您的侦听器是第一个被调用的侦听器

    function addListenerFirstInLine(emitter, eventName, listener) {
        // get existing listeners for the target event
        const listeners = emitter.listeners(eventName);
    
        // remove then all
        emitter.removeAllListeners(eventName);
    
        // add new listener first in line
        emitter.on(eventName, listener);
    
        // put back prior listeners after ours
        for (const fn of listeners) {
            emitter.on(eventName, fn);
        }
    }
    
    然后,您可以将其用于以下应用程序:

    addListenerFirstInLine(process, "uncaughtException", myListener)
    

    进程
    是一个事件发射器。这就是
    process.on('uncaughtException,…)
    的工作原理。您可以访问
    进程
    对象的EventEmitter部分,找到为
    未捕获异常注册的所有处理程序
    ,并对其进行操作以将您的处理放在第一位。这有点像黑客,但它是可以做到的。您甚至可以在
    进程
    对象上的
    上运行monkey patch
    。这样您就可以捕获该事件的任何后续侦听器。我明白了,让我看看我是否可以找到如何实现此功能的方法。听起来是可行的。
    进程
    是一个事件发射器。这就是
    process.on('uncaughtException,…)
    的工作原理。您可以访问
    进程
    对象的EventEmitter部分,找到为
    未捕获异常注册的所有处理程序
    ,并对其进行操作以将您的处理放在第一位。这有点像黑客,但它是可以做到的。您甚至可以在
    进程
    对象上的
    上运行monkey patch
    。这样您就可以捕获该事件的任何后续侦听器。我明白了,让我看看我是否可以找到如何实现此功能的方法。听起来是可行的。王-这回答了你的问题吗?如果是这样,您可以通过单击答案左侧的复选标记向社区表明这一点,这也将为您在这里遵循正确的程序赢得一些声誉点数。@aerowang-这回答了您的问题吗?如果是这样,您可以通过单击答案左侧的复选标记向社区表明这一点,这也将为您按照此处的正确程序赢得一些声誉点数。