【问题标题】:Express promise throw error快递承诺抛出错误
【发布时间】:2016-02-26 12:22:12
【问题描述】:

我正在使用带有 denodeify 模块的 Express。当我尝试异步呈现电子邮件模板时出现错误。

.then(function () {
     return denodeify(res.render)(path.resolve('verify-email'), {
         name: user.displayName,
         appName: config.app.title,
         mail: user.email,
         url: 'http://' + req.headers.host
     });
})
.then(function (emailHTML) {
     // code which is not executed
})
.catch(function (err) {
     // [TypeError: Cannot read property 'req' of undefined]
});

我尝试使用不带回调的 res.render 并且效果很好,但我需要在变量中输出电子邮件模板。 我也无法理解如何调试这部分代码。感谢帮助! 完整代码

function sendVerificationEmail(user, req, res) {
    return denodeify(crypto.randomBytes)(20)
        .then(function (buffer) {
            user.verificationToken = buffer.toString('hex');
            return user.save();
        })
        .then(function () {
            user.password = undefined;
            user.salt = undefined;
            delete req.session.redirect_to;

            return denodeify(res.render)(path.resolve('modules/users/server/templates/verify-email'), {
                name: user.displayName,
                appName: config.app.title,
                mail: user.email,
                url: 'http://' + req.headers.host + '/api/auth/verify/' + user.verificationToken + "/" + user.email
            });
        })
        .then(function (emailHTML) {
            const mailOptions = {
                to: user.email,
                from: config.mailer.from,
                subject: 'Verify Email',
                html: emailHTML
            };
            return denodeify(smtpTransport.sendMail)(mailOptions);
        });
}

exports.updateAuthData = function (req, res, next) {
    const userId = req.session.userId;
    delete req.session.userId;

    if (!userId) {
        return res.status(401).send({
            message: 'No active session'
        });
    }

    let user;

    User.findById(userId)
        .then()
        .then((_user) => {
            user = _user;

            const fields = Object.keys(req.body);
            const neededFields = user.getMissingAuthFields();
            const missingFields = _.difference(fields, neededFields);

            if (missingFields.length !== 0) {
                throw new CustomError('Missing fields: ' + missingFields.join(', '))
            }

            for (let field of User.requiredAuthorizationFields) {
                if (!!user[field]) {
                    throw new CustomError('User already has ' + field);
                }
            }

            User.requiredAuthorizationFields.forEach((field) => user[field] = req.body[field]);

            return true;
        })
        .then(function () {
            return sendVerificationEmail(user, req, res);
        })
        .then(() => {
            res.send({
                message: 'An email has been sent to the provided email, please verify your account.'
            });
        })
        .catch(function (err) {
            res.status(400).send({
                message: 'Failure sending email'
            });
        })
};

【问题讨论】:

  • 正如错误所说:req 未定义。你从哪里需要这个变量?
  • 你可以在没有 Promise 的情况下做到这一点,res.render('verify-email',{name:....}, function(err,emailHTML){ res.render('index',{ email: emailHTML }) });
  • 请添加整个函数。
  • 错误显示某些对象必须具有 .req 属性并且该对象未定义,所以我无法理解那是什么类型的对象..
  • 错误不是来自发布的代码 - 该错误清楚地表明错误是一段代码试图访问未定义的变量上的.req ...你还没有发布的代码有一个 something.**req** ...当然你可以从 nodejs 得到一个比消息更好的错误转储,你应该能够得到一个文件,行编号和堆栈跟踪

标签: javascript node.js asynchronous express promise


【解决方案1】:

我找到了解决方案,我们必须像这样绑定“this”变量

 return denodeify(res.render.bind(res))(path.resolve('modules/users/server/templates/verify-email'), {
      name: user.displayName,
      appName: config.app.title,
      mail: user.email,
      url: 'http://' + req.headers.host + '/api/auth/verify/' + user.verificationToken + "/" + user.email
 });

错误原因是 express "res.render" 函数中的以下代码

  var app = this.req.app;
  var done = callback;
  var opts = options || {};
  var req = this.req;
  var self = this;

正确的方法是使用:

denodeify(res.render.bind(res))(path, options)

而不是

denodeify(res.render)(path, options)

感谢大家的回复!

【讨论】:

    猜你喜欢
    • 2017-03-04
    • 2018-02-19
    • 1970-01-01
    • 1970-01-01
    • 2018-10-29
    • 1970-01-01
    • 1970-01-01
    • 2021-02-08
    • 1970-01-01
    相关资源
    最近更新 更多