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

Node.js使用aws-sdk SNS错误无法捕获及Mongoose事务异常问题

问题根因

  • 错误无法被catch捕获:sns.publish使用回调模式编写,回调为异步执行,触发时外层try/catch上下文已经销毁,抛出的错误无法被捕获,直接变为未捕获异常导致程序崩溃。
  • MongoTransactionError报错:代码没有等待sns.publish的执行结果就直接执行finally块的session1.endSession(),事务被提前终止,等回调触发调用commitTransaction时,事务已经处于结束/中止状态,因此抛出状态冲突错误。

修复方案

将sns.publish改为Promise调用形式,配合await等待执行结果,所有异步错误都可以被外层try/catch捕获,同时保证事务状态流转顺序正确。

修复后代码

// 依赖引入等逻辑保留在上方
const verifyPhone = async (req, res) => {
    const { phoneNumber } = req.body;
    const { userId } = req.user;
    let code = generateCode(6);

    const session1 = await mongoose.startSession();
    try {
        session1.startTransaction();

        const newCode = await PhoneCode.create(
            [
                {
                    userId,
                    code,
                },
            ],
            { session: session1 }
        );

        // 改为Promise形式调用sns.publish,用await等待执行结果
        const result = await sns.publish({
            MessageAttributes: {
                "AWS.SNS.SMS.SenderID": {
                    DataType: "String",
                    StringValue: "Testing",
                },
                "AWS.SNS.SMS.SMSType": {
                    DataType: "String",
                    StringValue: "Promotional",
                },
            },
            Message: "Your code: " + code,
            PhoneNumber: phoneNumber, // 替换原有硬编码的测试号码
        }).promise();

        // 短信发送成功后再提交事务
        await session1.commitTransaction();
        console.log("transaction committed");
        return res.status(200).json({ message: "SMS sent", result });
    } catch (e) {
        // 所有报错统一在此处处理,中止事务
        await session1.abortTransaction();
        return res.status(500).json({ message: "Something went wrong!", error: e });
    } finally {
        // 事务处理完成后再关闭会话
        await session1.endSession();
    }
};

module.exports = verifyPhone;

核心修改说明

  • 调用sns.publish后追加.promise()将回调方法转为Promise形式,使用await等待执行结果后,SNS抛出的所有错误(比如手机号格式错误、权限不足等)都能被外层try/catch正常捕获,不会出现未捕获异常。
  • 所有事务操作(commitTransaction、abortTransaction、endSession)都添加await,确保异步操作执行完成再进入下一步流程。
  • 流程调整为:SNS发送成功才提交事务,任意环节报错直接中止事务返回错误响应,完全避免事务状态冲突的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 03:54:03