Next.js调用Nodemailer发邮件出现API无响应报错问题咨询
问题根因&排查思路
这个报错的核心是Next.js API 路由要求所有请求路径下,都必须给客户端返回响应,不能存在无返回的分支,同时异步操作需要让框架感知到等待状态,避免框架提前结束请求生命周期。你可以按以下顺序排查:
- 异步操作未被框架感知:你当前的API处理函数是普通同步函数,内部调用异步的
sendMail时没有返回对应的Promise,Next.js 不知道你还有未完成的异步逻辑,会直接判定请求处理结束,此时你的异步逻辑还没走到返回响应的步骤,就会触发该报错。 - 错误分支未返回响应:
sendMail内部用try catch捕获错误后直接返回了error对象,而非抛出错误,这会导致外层的.catch完全不会被触发,所有错误都会走.then分支,属于逻辑漏洞- 外层的
.catch回调中仅打印了错误日志,没有调用res.status().json()返回响应,只要触发该分支就必然会出现题目中的报错
- 可选检查:可以先确认环境变量
process.env.GMAIL_UID、process.env.GMAIL_PW是否能正常读取,邮箱SMTP服务的IP白名单、端口配置是否正确,很多时候发邮件报错都是SMTP配置异常触发了无返回的错误分支。
修复后的代码示例
const nodemailer = require('nodemailer'); // 改为async异步函数,让框架感知异步操作 export default async function (req, res) { try { const mailData = { from: 'xxxxx', to: req.body.email, subject: 'Message to Full On Consulting', text: req.body.message, html: '<div>'+req.body.message+'</div>' } const result = await sendMail(mailData) // 判断返回结果是否为错误,避免异常状态返回200 if (result instanceof Error) { console.log('Email send error', result.message); return res.status(500).json({ status: 'FAIL', message: result.message }) } console.log('Email sent...', result); return res.status(200).json({ status: 'SUCCESS' }) } catch (error) { // 全局捕获所有异常,统一返回响应 console.log('Request error ... ' + error.message); return res.status(500).json({ status: 'FAIL', message: '邮件发送失败' }) } } async function sendMail(mailData) { try { let transport = nodemailer.createTransport({ host: "mail.xxxxxxxxxx.com", port: 587, secure: false, auth: { user: process.env.GMAIL_UID, pass: process.env.GMAIL_PW } }); const result = await transport.sendMail(mailData) return result; } catch (error) { console.log("CATCH ERROR: " + error) // 若需要外层直接捕获异常可改为 throw error return error; } }
内容的提问来源于stack exchange,提问作者Don
相关产品推荐
相关产品推荐

