Lambda中Stripe订阅未执行——异步代码问题排查
解决Lambda异步函数中Stripe客户与订阅创建的问题
看起来你遇到的核心问题是混用了async/await和传统的.then()链式调用,再加上Lambda函数提前返回导致订阅创建的异步操作还没完成就终止了。咱们一步步来修复:
问题根源
- 你在
.then()的回调函数里尝试用await,但这个回调本身不是async函数,所以会触发“无法在非异步函数中使用await”的报错。 - 你的Lambda函数最后直接调用
return callback(null, output),这时候创建订阅的异步请求还在后台运行,Lambda不会等待它完成就结束了,所以只生成了客户却没创建订阅。
修复方案:统一使用async/await风格
把整个流程改成纯async/await写法,抛弃.then()链式调用,这样既能解决await的报错问题,又能确保Lambda等待所有异步操作完成后再返回。
修改后的代码如下:
module.exports.stripe = async (event, context, callback) => { context.callbackWaitsForEmptyEventLoop = false; let input = JSON.parse(event.Records[0].body); let message = JSON.parse(input.Message) let companyID = message.companyID let plan = message.plan let email = message.email let output = {} try { // 1. 等待客户创建完成 const customer = await stripe.customers.create({ email, description: companyID }); console.log('Created customer:', customer); if (customer.id) { // 2. 等待订阅创建完成 const subscription = await stripe.subscriptions.create({ customer: customer.id, trial_period_days: 14, items: [{ plan }] // coupon 可以在这里添加 }); console.log('Created subscription:', subscription); if(subscription.id) { console.log('Successfully created subscription: ', subscription.id); // 可按需将订阅ID加入返回结果 output.subscriptionId = subscription.id; } else { console.log('Error creating subscription for: ', customer.id); } } // 所有操作完成后再通知Lambda结束 return callback(null, output); } catch (err) { console.log('Error occurred:', err); // 按原有逻辑处理不同类型的Stripe错误 if (err && err.type) { switch (err.type) { case 'StripeCardError': console.log('Card error:', err.message); break; case 'RateLimitError': console.log('Rate limit exceeded'); break; case 'StripeInvalidRequestError': console.log('Invalid request parameters'); break; case 'StripeAPIError': console.log('Stripe internal API error'); break; case 'StripeConnectionError': console.log('HTTPS communication error'); break; case 'StripeAuthenticationError': console.log('Incorrect API key'); break; default: console.log('Unexpected error'); break; } } // 将错误传递给Lambda的回调 return callback(err, output); } };
关键改动说明
- 统一用
await等待异步操作:不管是创建客户还是订阅,都用await等待Promise完成,确保前一步执行完毕后再启动下一步。 - 用
try/catch处理错误:代替原来的.catch()链式调用,更符合async/await的代码风格,也能统一捕获所有异步操作的错误。 - 延迟调用
callback:把callback放在try和catch的最后,确保所有异步操作(客户创建+订阅创建)都完成后,再通知Lambda函数终止。 - 移除
.then()链式调用:避免在async函数里混用两种异步写法,让代码更易读、更易维护。
这样修改后,Lambda函数会先等待客户创建成功,再等待订阅创建完成,之后才会返回结果,不会再出现只创建客户的情况了。
内容的提问来源于stack exchange,提问作者joshk132
相关产品推荐
相关产品推荐

