使用AWS Lambda与API Gateway时出现502错误的排查与解决
问题:AWS Lambda + API Gateway对接Plaid时502错误(无法接收请求体参数)
作为AWS新手,我在使用Lambda和API Gateway对接Plaid生成Link Token时遇到502错误。具体情况:
- 硬编码
client_user_id: '1'时,Lambda能正常返回Link Token; - 通过前端或API Gateway测试页面传入
{"clientUserId": "1"}时,CloudWatch显示Lambda未接收到clientUserId,user对象为空,同时触发502错误。
相关代码
Lambda代码(linktokenfunction.js)
const client = new PlaidApi(configuration); const plaidConfig = { client_name: 'FinPilot', products: ['auth', 'transactions'], language: 'en', country_codes: ['US'], }; app.post('/plaidLinkToken', async function (req, res) { const linkTokenResponse = await client.linkTokenCreate({ user: { client_user_id: req.body.clientUserId, }, client_name: plaidConfig.client_name, products: plaidConfig.products, language: plaidConfig.language, country_codes: plaidConfig.country_codes, }); try { const link_token = linkTokenResponse.data.link_token; res.json({link_token}); } catch (error) { // handle error } });
前端按钮代码
async function getLinkToken() { let token = await API.post('plaidTokenAPI', '/plaidLinkToken', { clientUserId: '1', }); token = token.link_token; setLinkToken(token); setShowLinkCardModal(true); console.log(linkToken); }
错误原因
- 请求体解析问题:API Gateway默认不会自动将JSON请求体解析为Lambda可用的对象,若直接使用Express的
req.body且未配置事件转换,req.body会为空。 - 错误处理缺失:原代码中
linkTokenCreate调用放在try块外,参数缺失导致Plaid接口调用失败时,未捕获错误并返回合法响应,Lambda抛出未处理异常,被API Gateway转换为502错误。 - 集成配置遗漏:API Gateway的集成请求未设置正确的请求体传递规则,前端传入的参数无法到达Lambda。
解决方法
方案1:原生Lambda处理(无需Express)
修改Lambda代码,直接解析API Gateway的事件对象:
const client = new PlaidApi(configuration); const plaidConfig = { client_name: 'FinPilot', products: ['auth', 'transactions'], language: 'en', country_codes: ['US'], }; exports.handler = async (event) => { try { // 解析API Gateway传递的请求体 const requestBody = JSON.parse(event.body); // 调用Plaid接口生成Link Token const linkTokenResponse = await client.linkTokenCreate({ user: { client_user_id: requestBody.clientUserId, }, ...plaidConfig }); // 返回标准Lambda响应 return { statusCode: 200, headers: { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' // 根据实际域名调整CORS配置 }, body: JSON.stringify({ link_token: linkTokenResponse.data.link_token }) }; } catch (error) { console.error('生成Link Token失败:', error); // 返回错误响应,避免Lambda抛出未处理异常 return { statusCode: 500, headers: { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' }, body: JSON.stringify({ error: error.message }) }; } };
同时配置API Gateway:
- 进入对应API的
POST方法,在集成请求中设置“请求体传递方式”为Passthrough; - 在方法请求中添加
Content-Type请求头,值为application/json。
方案2:保留Express框架(使用Serverless Express)
若坚持使用Express,需引入aws-serverless-express包转换Lambda事件:
- 安装依赖:
npm install aws-serverless-express - 创建Lambda入口文件(如
handler.js):
const awsServerlessExpress = require('aws-serverless-express'); const app = require('./linktokenfunction'); // 导入你的Express app const server = awsServerlessExpress.createServer(app); exports.handler = (event, context) => { awsServerlessExpress.proxy(server, event, context); };
- 修改原Express代码的错误逻辑,将
linkTokenCreate放入try块:
app.post('/plaidLinkToken', async function (req, res) { try { const linkTokenResponse = await client.linkTokenCreate({ user: { client_user_id: req.body.clientUserId, }, ...plaidConfig }); const link_token = linkTokenResponse.data.link_token; res.json({link_token}); } catch (error) { console.error('错误:', error); res.status(500).json({ error: error.message }); } });
- 配置API Gateway集成请求:在集成请求的“模板”中添加
application/json模板,内容为$input.json('$'),确保请求体被正确传递到Express的req.body。
内容的提问来源于stack exchange,提问作者Nathan Nguyen
相关产品推荐
相关产品推荐

