Обещать Nodemailer с bluebird?

автор nodemailer ясно дал понять, что не поддерживает обещания. Я думал, что попробую свои силы в использовании bluebird, но моя попытка, похоже, не обнаружила никаких ошибок, которые выдает Nodemailer:

var nodemailer = require('nodemailer');
var Promise = require('bluebird');

// build the transport with promises
var transport = Promise.promisifyAll( nodemailer.createTransport({...}) );

module.exports = {
    doit = function() {
        // Use bluebird Async
        return transport.sendMailAsync({...});
    }
}

Затем я вызываю это, делая:

doit().then(function() {
    console.log("success!");
}).catch(function(err) {
    console.log("There has been an error");
});

Однако при указании недействительного адреса электронной почты я вижу это:

Unhandled rejection Error: Can't send mail - all recipients were rejected

Итак, ошибка nodemailer не перехватывается моим обещанием bluebird. Что я сделал не так?


person fanhats    schedule 20.06.2015    source источник
comment
Вы не показываете нам весь свой код — пожалуйста, сделайте версию, которая его воспроизводит, а также — в какой строке находится необработанная ошибка отклонения? (Тот факт, что вы получаете это сообщение, указывает на то, что bluebird действительно видит ошибку.   -  person Benjamin Gruenbaum    schedule 20.06.2015
comment
та же проблема с грубыми методами Couchbase.   -  person Reza Owliaei    schedule 13.12.2015


Ответы (5)


Не могу сказать, что не так с кодом из моей головы. Я столкнулся с похожими проблемами с обещаниями и решил, что вместо этого проще просто обещать проблемные случаи вручную. Это не самое элегантное решение, но это решение.

var transport = nodemailer.createTransport({...});

module.exports = {
    doit: function() {
        return new Promise(function (res, rej) {
           transport.sendMail({...}, function cb(err, data) {
                if(err) rej(err)
                else res(data)
            });
        });
    }
}
person Juho    schedule 20.06.2015

Вот как я заработал (машинопись, обещание синей птицы, nodemailer-smtp-transport):

export const SendEmail = (from:string,
                          to:string[],
                          subject:string,
                          text:string,
                          html:string) => {

    const transportOptions = smtpConfiguration; // Defined elsewhere

    const transporter = nodemailer.createTransport(smtpTransport(transportOptions));

    const emailOptions = {
        from: from,
        to: to.join(','),
        subject: subject,
        text: text,
        html: html
    };

    return new Promise((resolve, reject) => {
        transporter.sendMail(emailOptions, (err, data) => {
            if (err) {
                return reject(err);
            } else {
                return resolve(data);
            }
        });
    });
};
person Mike Cheel    schedule 19.07.2016

Вы можете попробовать создать обещание "на лету" с помощью .fromNode()?

var nodemailer = require('nodemailer');
var Promise = require('bluebird');

module.exports = {
    doit = function() {            
        return Promise.fromNode(function(callback) {
            transport.sendMail({...}), callback);
        }
    }
}

doit() вернет обещание bluebird. Вы можете найти документы для .fromNode() здесь.

person naartjie    schedule 20.09.2015

Если вам просто нужен Promisify метод .sendMail, вы можете сделать так:

const transport = nodemailer.createTransport({
  host: mailConfig.host,
  port: mailConfig.port,
  secure: true,
  auth: {
    user: mailConfig.username,
    pass: mailConfig.password,
  },
});

const sendMail = Promise.promisify(transport.sendMail, { context: transport });

И используя это так:

const mailOptions = {
  from: ...,
  to: ...,
  subject: ...,
  html: ...,
  text: ...,
};

sendMail(mailOptions)
  .then(..)
  .catch(..);

Или, если вы используете async/await, завернутый в асинхронную функцию:

./mail.js

const send = async (options) => {
  ...

  return sendMail(options);
};

export default { send };

И await когда вы его используете

./testing.js

import mail from './mail';

await mail.sendMail(options);

Вы поняли идею.

person Noval Parinussa    schedule 11.06.2018

Теперь, если вы просто пропустите обратный вызов, он вернет обещание.

Пример

const nodemailer = require('nodemailer')

const transport = nodemailer.createTransport({
    host: 'smtp_host',
    port: 'smpt_port',
    auth: {
        user: 'smpt_auth_user',
        pass: 'smpt_auth_password',
    },
})

const promise = transport.sendMail({
    from: '[email protected]',
    to: '[email protected]',
    text: 'Hello world!',
    subject: 'Test'
})

console.log(promise)

Этот журнал выше вернет Promise { <pending> }

person João Pedro    schedule 05.07.2021
comment
Вы имели в виду возвраты? Можете ли вы показать код? - person tomasantunes; 05.07.2021
comment
Привет @tomas, я изменил ответ и добавил пример. - person João Pedro; 08.07.2021