首页 > 解决方案 > 节点 uncaughtException 处理程序中的异步代码

问题描述

我有一个节点应用程序(版本 8.11.1,使用 Typescript 2.8.1),它使用如下uncaughtException钩子捕获未捕获的异常:

process.on('uncaughtException', (err) => {
    await sendEmail(recipient, subject, body);
});

我在处理程序中调用异步方法来发送电子邮件,但代码不起作用。似乎节点进程在异步调用完成之前就死了,我从来没有收到过电子邮件。

看起来您可能无法在此处理程序中成功使用异步方法。该文档并没有直接说,但它暗示它说明

'uncaughtException' 的正确用法是对分配的资源进行同步清理

我没有尝试恢复操作或做任何时髦的事情。我要做的就是发送电子邮件,说明系统崩溃了。我找不到任何可以同步发送电子邮件的库,所以我对如何处理这个问题有点茫然。

我看到一个建议将数据同步写入文件(或数据库)并进行一些外部处理轮询该文件的存在并在它存在时发送电子邮件。我想这会起作用,但它很hacky。有更好的解决方案吗?

更新:

好吧,在运行更多测试之后,看起来您实际上可以从uncaughtException处理程序内部运行异步代码就好了。以下作品:

const mailer = require('nodemailer');

process.on('uncaughtException', async err => {
    const transport = mailer.createTransport({
        service: 'gmail',
        auth: {
            user: 'someone@email.com',
            pass: 'abc'
        }
    });

    const mailOptions = {
        from: 'someone@email.com',
        to: 'someone.else@email.com',
        subject: 'hi',
        text: 'there'
    };

    transport.sendMail(mailOptions, (error, info) => {
        if (error) {
            console.log(error);
        }
        else {
            console.log(info);
        }
    });
});

throw new Error('boom');

上面的代码作为一个独立的应用程序可以正常工作,但是如果我将它复制到我的代码库中,它就不起作用了。代码执行,但我没有收到电子邮件(大概应用程序在完成发送之前就死了)。因此,我的环境中一定有其他事情正在阻止它工作。我会继续挖掘。

标签: node.jsemailasynchronousexception

解决方案


我不知道您使用什么库来发送电子邮件以及您使用的节点 js 版本,但如果您使用的节点 js 版本大于 7,您可以使用 async/await 并发送电子邮件,如下所示

var mailgun = require('mailgun-js')({apiKey: api_key, domain: domain});


process.on('uncaughtException', async (err) => {
    var data = {
    from: 'User <me@samples.mailgun.org>',
    to: 'serobnic@mail.ru',
    subject: 'ERROR MESSAGE',
    text: `Caught exception: ${err}\n`,
  };
  
  var body = await mailgun.messages().send(data);
  console.log(body);
});

// using callback - supported for all versions

process.on('uncaughtException', (err) => {
    var data = {
    from: 'User <me@samples.mailgun.org>',
    to: 'serobnic@mail.ru',
    subject: 'ERROR MESSAGE',
    text: 'Caught exception:' + err,
  };
  
   mailgun.messages().send(data, function (err, body) {
     console.log(body);
   });
});


推荐阅读