You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

首次使用Nodemailer向Ethereal Mail发件报错:Cannot read properties of undefined (reading 'messageId')

Nodemailer发送Ethereal邮件报错排查:Cannot read properties of undefined (reading 'messageId')

首次使用Nodemailer发送邮件,尝试向Ethereal Mail发送时失败,报错信息:Cannot read properties of undefined (reading 'messageId')

控制台日志

[2022-10-18 14:08:55] DEBUG Creating transport: nodemailer (6.8.0; +https://nodemailer.com/; SMTP/6.8.0[client:6.8.0])
[2022-10-18 14:08:55] DEBUG Sending mail using SMTP/6.8.0[client:6.8.0]
Error occurred. Cannot read properties of undefined (reading 'messageId')
::1 - - [18/Oct/2022:14:08:55 +0000] "POST /posts HTTP/1.1" 200 10 "http://localhost:5000/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36"
[2022-10-18 14:08:55] DEBUG [AO7ADWBuDE] Resolved smtp.ethereal.email as 54.36.85.113 [cache miss]

相关代码

utils/nodemailer.js

export async function sendMail(username, address, text) {
  // 创建SMTP传输器对象
  let transporter = nodemailer.createTransport({
    host: 'smtp.ethereal.email',
    port: 587,
    auth: {
      user: 'diego.marks28@ethereal.email',
      pass: 'YvQ1FS9g8Ut8qWE1Jz',
    },
    debug: true,
    logger: true,
  });
  // transporter.verify((err, success) => {
  //   if (err) console.error(err);
  //   console.log('配置正确');
  // });


  let message = {
    from: 'do_not_reply@northpole.com',
    to: 'santa@northpole.com',
    subject: 'New wish from a child has been requested!',
    html: `<p>Dear Santa Clause,<br>
        A child has sent his wish. Below are the details.<br>
        <ul>Username: ${username} </ul>
        <ul>Address: ${address}</ul>
        <ul>Wish: ${text}</ul>
        </p>`,
  };
  return transporter.sendMail(message, (error) => {
    if (error) {
      return console.log(error);
    }
    console.log(info);
  });

  // 仅通过Ethereal账户发送时可预览
}

server.js

app.post('/posts', async (request, response) => {
  const { username, address, text } = request.body;
  await addPost(username, address, text);

  try {
    const data = await sendMail(username, address, text);
    console.log('Message sent: %s', data.messageId);
    return response.json({
      username: username,
      address: address,
      text: text,
    });
  } catch (err) {
    console.log('Error occurred. ' + err.message);
    return response.send('error here');
  }
});

问题原因

  1. 返回值不匹配异步逻辑:sendMail是async函数,但内部使用了transporter.sendMail的回调模式,该模式下不会返回Promise,导致await sendMail(...)得到的data是undefined,访问data.messageId触发报错。
  2. 错误未向上抛出:回调里的错误仅用console.log打印,未抛出异常,导致server.js的try/catch无法捕获错误,无法正确处理失败场景。
  3. 未定义变量:回调中的console.log(info)里info变量未声明,会引发额外错误。

修复方案

将sendMail改为Promise模式(Nodemailer原生支持Promise返回),修改后的代码如下:

修改后的utils/nodemailer.js

export async function sendMail(username, address, text) {
  // 创建SMTP传输器对象
  let transporter = nodemailer.createTransport({
    host: 'smtp.ethereal.email',
    port: 587,
    auth: {
      user: 'diego.marks28@ethereal.email',
      pass: 'YvQ1FS9g8Ut8qWE1Jz',
    },
    debug: true,
    logger: true,
  });

  // 可选:验证配置是否正确
  // await transporter.verify();
  // console.log('配置正确');

  let message = {
    from: 'do_not_reply@northpole.com',
    to: 'santa@northpole.com',
    subject: 'New wish from a child has been requested!',
    html: `<p>Dear Santa Clause,<br>
        A child has sent his wish. Below are the details.<br>
        <ul>Username: ${username} </ul>
        <ul>Address: ${address}</ul>
        <ul>Wish: ${text}</ul>
        </p>`,
  };

  // 直接返回sendMail的Promise结果
  const info = await transporter.sendMail(message);
  console.log(info);
  return info;
}

说明

  • 移除回调函数,直接用await获取transporter.sendMail的返回值,确保sendMail函数返回包含messageId的对象,server.js中的data能正确获取值。
  • 发送过程中的错误会自动被Promise抛出,server.js的try/catch可以捕获并处理。
  • 修复了未定义的info变量问题。

内容的提问来源于stack exchange,提问作者Johnspeed114

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 09:20:31