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

Docker环境中Nodemailer调用sendMail报未定义属性错误排查

Hey there! Let's break down why you ran into that Cannot read property 'sendMail' of undefined error, and explain why your fix works (plus share another approach if you want to optimize transporter reuse).

What Caused the Error

The key issue here is your sendHtmlMail method is marked as static. Static methods belong to the class itself, not to individual instances of the class. When you’re inside a static method, this refers to the class constructor—not the instance you created with new Mailer().

That’s why console.log(this.transporter) returned undefined: the transporter you initialized in the class constructor is an instance-specific property, and static methods can’t access properties tied to class instances. When you tried to call this.transporter.sendMail, you were trying to access a property that doesn’t exist on the class itself.

Why Your Fixed Code Works

In your updated version, you moved the transporter creation directly inside the static sendHtmlMail method. Now transporter is a local variable within the method’s scope, so you don’t have to rely on this to access it. This completely bypasses the static method limitation, letting you call transporter.sendMail without any undefined errors.

Another Option: Reuse the Transporter with Instance Methods

If you want to avoid creating a new transporter every time you send an email (more efficient), you can remove the static keyword from sendHtmlMail and use an instance of the Mailer class instead:

import logger from 'config/logger'
import nodemailer from 'nodemailer'

export default class Mailer {
 constructor() {
 this.transporter = nodemailer.createTransport({
 host: 'smtp.ethereal.email',
 port: 587,
 secure: false,
 auth: {
 user: 'claudie.schmitt@ethereal.email',
 pass: 'DnWah2bRbw3K5bqyke'
 },
 tls: {
 rejectUnauthorized: false,
 }
 })
 }

 async sendHtmlMail({ to, subject, text }) {
 console.log("SENDING EMAIL")
 console.log(to)
 console.log(subject)
 console.log(this.transporter)
 try {
 // Use async/await directly (sendMail returns a promise, no need for callbacks!)
 const info = await this.transporter.sendMail({
 from: 'claudie.schmitt@ethereal.email',
 to,
 subject,
 html: text,
 })
 console.log("SENT MAIL")
 logger.info('info', info)
 } catch (err) {
 console.log("NO SENT MAIL")
 logger.error('err', err)
 }
 return true
 }
}

// Usage example:
const mailerInstance = new Mailer();
await mailerInstance.sendHtmlMail({ 
 to: 'recipient@example.com', 
 subject: 'MyCV created', 
 text: '<h1>Your CV is ready!</h1>' 
});

A quick tip: I removed the callback from sendMail here because Nodemailer’s sendMail supports Promises natively. Mixing await and callbacks can lead to unexpected behavior, so sticking with async/alone makes the code cleaner and easier to debug.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 10:52:42