错误处理不适用于 Express 中的 Nodemailer

Error handling not working for Nodemailer in Express

我有一个使用nodemailer阅读邮件的功能:MailRead.js

exports.sendMailService = async (mailOptions) => {
    return new Promise((resolve, reject) => {
        mailOptions.from = 'someemail@some.com'
        const transporter = nodemailer.createTransport({
            service: some,
            auth: {
                user: 'somemail@some.com',
                pass: 'password'
            }
        });
        transporter.sendMail(mailOptions, function (error, info) {
            if (error) {
                console.log("error is " + error);
                resolve(false); // or use rejcet(false) but then you will have to handle errors
            }
            else {
                console.log('Email sent: ' + info.response);
                resolve(true);
            }
        });
    })
}

当我在控制器中调用这个函数时:sendController.js

exports.sendMail = async (req, res, next) => {
    const mailBody = req.body
    try{
        await sendMailService(mailOptions)
        //if I do this:
        //const mailSent = await sendMailService(mailOptions)
        //if every credential is correct it mailSent displays true if not credentials false it gives 
        //false
        //but I want to handle error not just check for condition.
    }catch (err){ //not coming to catch part
        next(ApiError.badClientError('Bad Credentials')); //some function to handle error
            return;
    }
};

当调用 api 时:触发上述函数:

Apisample:

api.post('sendmail',sendMail);

我也试过 this SO:但我认为它对我不起作用。

那么对于虚假凭证有什么建议应该去捕获语句吗?

您的 sendMail() 函数假设对 sendMailService() 的失败调用将拒绝它 returns 的承诺。但是,一旦出错,您的 sendMailService() 函数会调用 resolve(false),而不是 reject(someError)。因此,你的 await sendMailService() 永远不会抛出并且你永远不会到达你的 catch 块。

如果相反,您在错误时拒绝,它将到达您的 catch 区块:

exports.sendMailService = async (mailOptions) => {
    return new Promise((resolve, reject) => {
        mailOptions.from = 'someemail@some.com'
        const transporter = nodemailer.createTransport({
            service: some,
            auth: {
                user: 'somemail@some.com',
                pass: 'password'
            }
        });
        transporter.sendMail(mailOptions, function (error, info) {
            if (error) {
                console.log("error is ", error);
                // reject the returned promise with the error
                reject(error);
            } else {
                console.log('Email sent: ' + info.response);
                resolve(true);
            }
        });
    })
}