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

Node.js报错时关闭Post请求连接并返回Postman响应

问题:Express邮件接口报错时Postman无限加载,无法返回响应

我用Express写了一个邮件发送接口,当sendEmail执行报错时(代码注释标记位置),Postman会无限加载,没法收到响应。试过返回不同的res.json数据但没用,相关代码如下:

import express, { Request, Response } from "express";
import { sendEmail } from "../../mailsend/SendMail";
// будт приходить с клиента три массива [connectionData: {from, pass}] [sendMail: {to}] [dataText: {subject, text}]

const routerMailSend = express.Router();

routerMailSend.post("/", async (req: Request, res: Response) => {
  if (!req.body) {
    return res.status(400).send("Missing from property in request body");
  }
  console.log(req.body);

  const { connectionData, dataText, sendMail } = req.body //В таком виде будут приходить с клиента массивы
//   const { from, pass, to, subject, text } = req.body;
  try{
    const promises = sendMail.map(async (recipient: string) => {
        const {from, pass} = connectionData[Math.floor(Math.random() * connectionData.length)];
        const {subject, text} = dataText[Math.floor(Math.random() * dataText.length)];
        console.log(from, pass);
        
        return new Promise((resolve, reject) => {
            setTimeout( async () => {
              try {
                  const transfer = await sendEmail(from, pass, recipient, subject, text);
                  console.log("message send process");
                  resolve(transfer);
              } catch (err) {
                  console.log("Connect refused");
                  reject(new Error("Incorrect login or password"))        // ----------Close the post request connection if an error occurs at this location and return the response to postman          
              }
            }, Math.floor(Math.random() * (10000 - 3000 + 1) + 3000))
        })
      })

      const results = await Promise.all(promises);
      res.status(200);

      return res.json({ message: "Message send access" });
  } catch (err) {
      res.status(400);
      return ({ message: "Message send error" });
  }
});

export default routerMailSend;

解决方案

问题根源

  1. Promise.all错误捕获后的响应缺失:虽然Promise.all会在任一Promise reject时抛出错误,但你的catch块只是返回了一个对象,没有调用res.json()或res.send()来结束请求,导致Postman一直等待响应。
  2. 冗余的Promise嵌套:手动创建Promise包裹setTimeout和异步逻辑,写法冗余且容易出错。

修改后的代码

import express, { Request, Response } from "express";
import { sendEmail } from "../../mailsend/SendMail";

const routerMailSend = express.Router();

routerMailSend.post("/", async (req: Request, res: Response) => {
  if (!req.body) {
    return res.status(400).send("Missing from property in request body");
  }
  console.log(req.body);

  const { connectionData, dataText, sendMail } = req.body;

  try {
    const promises = sendMail.map(async (recipient: string) => {
      // 随机选取邮件配置
      const { from, pass } = connectionData[Math.floor(Math.random() * connectionData.length)];
      const { subject, text } = dataText[Math.floor(Math.random() * dataText.length)];
      console.log(from, pass);

      // 简化延迟逻辑,避免手动创建Promise
      await new Promise(resolve => setTimeout(resolve, Math.floor(Math.random() * (10000 - 3000 + 1) + 3000)));
      
      // 执行邮件发送,失败直接抛出错误
      const transfer = await sendEmail(from, pass, recipient, subject, text);
      console.log("message send process");
      return transfer;
    });

    await Promise.all(promises);
    return res.status(200).json({ message: "Message send access" });
  } catch (err) {
    console.log("Connect refused", err);
    // 必须调用res.json返回响应,主动结束请求
    return res.status(400).json({ message: "Message send error", error: (err as Error).message });
  }
});

export default routerMailSend;

可选优化:快速失败模式

如果需要在第一个错误发生时立即返回响应(无需等待所有Promise完成),可以替换Promise.all为循环逐个执行:

try {
  for (const recipient of sendMail) {
    const { from, pass } = connectionData[Math.floor(Math.random() * connectionData.length)];
    const { subject, text } = dataText[Math.floor(Math.random() * dataText.length)];
    console.log(from, pass);

    await new Promise(resolve => setTimeout(resolve, Math.floor(Math.random() * (10000 - 3000 + 1) + 3000)));
    await sendEmail(from, pass, recipient, subject, text);
    console.log("message send process");
  }
  return res.status(200).json({ message: "Message send access" });
} catch (err) {
  console.log("Connect refused", err);
  return res.status(400).json({ message: "Message send error", error: (err as Error).message });
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 08:33:22