Sushant Rad
Sushant Rad

Reputation: 339

Error handling not working for Nodemailer in Express

I have a function to read mails using nodemailer:MailRead.js

exports.sendMailService = async (mailOptions) => {
    return new Promise((resolve, reject) => {
        mailOptions.from = '[email protected]'
        const transporter = nodemailer.createTransport({
            service: some,
            auth: {
                user: '[email protected]',
                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);
            }
        });
    })
}

When I'm calling this function in a controller :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;
    }
};

When an api is call : above function is triggered :

Apisample:

api.post('sendmail',sendMail);

Also I tried this SO: but I don't think its working for me.

So is there any suggestion on false credentials it should go to catch statement?

Upvotes: 1

Views: 522

Answers (1)

jfriend00
jfriend00

Reputation: 707148

Your sendMail() function is assuming that a failed call to sendMailService() will reject the promise it returns. But, upon error, your sendMailService() function calls resolve(false), not reject(someError). Thus, your await sendMailService() never throws and you never get to your catch block.

If instead, you reject upon error, it will then get to your catch block:

exports.sendMailService = async (mailOptions) => {
    return new Promise((resolve, reject) => {
        mailOptions.from = '[email protected]'
        const transporter = nodemailer.createTransport({
            service: some,
            auth: {
                user: '[email protected]',
                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);
            }
        });
    })
}

Upvotes: 2

Related Questions