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

NodeJS升级SOAP模块(1.0.0)后出现req.then is not a function错误排查

排查soap模块1.0.0升级后req.then is not a function错误

核心问题分析

升级soap模块到1.0.0后出现req.then is not a function错误,根源在于soap 1.x版本内部对请求函数的Promise化要求:旧版soap模块兼容回调风格的request库,但1.x版本会尝试对传入的request调用.then()方法,而你当前使用的request.defaults()返回的对象是回调风格,不支持Promise链式调用,因此触发错误。

排查步骤

  1. 确认request库版本与soap的兼容性
    soap 1.0.0要求请求函数返回Promise,而传统的request@2.x默认是回调风格,不自带Promise支持。执行以下命令查看当前request版本:

    npm list request
    
  2. 验证request选项的调用方式
    检查soap_client_options中的request属性:soap模块会将请求逻辑委托给这个函数,1.x版本期望它返回一个Promise对象,而request.defaults()返回的是一个回调风格的函数,无法满足这个要求。

修复方案

方案1:替换为支持Promise的request库

改用request-promise-native(轻量级,基于原生Promise),它的API与request兼容,但默认返回Promise:

  1. 安装依赖:
    npm install request-promise-native --save
    
  2. 修改代码:
    const request = require('request-promise-native'); // 替换原request引入
    const url = 'https://example.com/wsi/service.php?wsdl';
    
    let args = {
        username: 'username',
        authKey: 'auth_key',
        sender: '',
        recipient: req.user.phone,
        message: '',
        scheduleDate: '',
        validity: '',
        callbackUrl: ''
    };
    
    // 保持defaults配置不变
    let request_with_defaults = request.defaults({ 'proxy': 'proxy', 'timeout': 5000, 'connection': 'keep-alive' });
    let soap_client_options = { 'request': request_with_defaults };
    
    args.message = generateSMSCode(req, codeTime);
    args.recipient = req.user.phone; // 修正变量引用问题,原代码中phone未定义
    
    // 改用soap的Promise风格API(更符合1.x版本设计)
    soap.createClient(url, soap_client_options)
      .then(client => client.sendSmsAuthKey(args))
      .then(result => {
          console.log(currentDateTime.getCurrentDate() + " - Code Sent at " + codeDateTime + "!");
          res.redirect('/auth/validate');
      })
      .catch(err => {
          console.log(currentDateTime.getCurrentDate() + " - ERROR!");
          console.log(err);
      });
    

方案2:包装传统request为Promise风格

如果不想替换库,可以手动包装request函数,让它返回Promise:

const request = require('request');
const url = 'https://example.com/wsi/service.php?wsdl';

// 包装request为Promise风格
function promisifiedRequest(options) {
  return new Promise((resolve, reject) => {
    request(options, (err, response, body) => {
      if (err) return reject(err);
      resolve({ response, body });
    });
  });
}

let args = {
    username: 'username',
    authKey: 'auth_key',
    sender: '',
    recipient: req.user.phone,
    message: '',
    scheduleDate: '',
    validity: '',
    callbackUrl: ''
};

// 用包装后的函数替代request.defaults返回的对象
let soap_client_options = { 'request': promisifiedRequest };

args.message = generateSMSCode(req, codeTime);
args.recipient = req.user.phone;

// 原回调风格代码可继续使用
soap.createClient(url, soap_client_options, function(err, client) {
    if (err) {
        console.log(currentDateTime.getCurrentDate() + " - ERROR!");
        console.log(err);
        return;
    }
    client.sendSmsAuthKey(args, function(err, result) {
        if (err) {
            console.log(currentDateTime.getCurrentDate() + " - ERROR!");
            console.log(err);
        } else {
            console.log(currentDateTime.getCurrentDate() + " - Code Sent at " + codeDateTime + "!");
            res.redirect('/auth/validate');
        }
    });
});

额外代码优化提示

  • 原代码中args.recipient = phone;的phone变量未定义,建议修正为req.user.phone或确保变量已正确声明。
  • 升级后建议逐步迁移到soap模块的Promise风格API,回调风格虽然兼容,但Promise更符合Node.js现代异步编程规范。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 09:34:53