Lambda调用DynamoDB.update后无日志静默失败,请求协助排查
问题排查:Lambda处理DynamoDB流时执行update后异常终止无日志
我使用Lambda函数处理DynamoDB插入流,执行dynamoDB.update调用后,Lambda异常终止且无后续日志输出。移除更新逻辑后日志恢复正常,代码如下:
/* Amplify Params - DO NOT EDIT API_SCHOLARGRAPH_EMPLOYEEINFOTABLE_ARN API_SCHOLARGRAPH_EMPLOYEEINFOTABLE_NAME ENV REGION Amplify Params - DO NOT EDIT */ const AWS = require('aws-sdk'); const awsConfig = { region: process.env.REGION, endpoint: process.env.DYNAMODB_ENDPOINT || `https://dynamodb.${process.env.REGION}.amazonaws.com` }; const dynamoDB = new AWS.DynamoDB.DocumentClient(awsConfig); async function handleNewEmployeeInfo(dynamoId, employeeId) { console.log( `[handleNewEmployeeInfo] begin. dynamoId(${dynamoId}) employeeId(${employeeId})` ); try { const employeeName = "TestString"; // this log is working console.log( 'try to update table:', process.env.API_SCHOLARGRAPH_EMPLOYEEINFOTABLE_NAME, dynamoId, employeeName ); // something wrong with the update await dynamoDB .update({ TableName: process.env.API_SCHOLARGRAPH_EMPLOYEEINFOTABLE_NAME, Key: { id: dynamoId }, UpdateExpression: `set employeeName = :employeeName`, ExpressionAttributeValues: { ':employeeName': employeeName } }) .promise() .then((data) => console.log(data.Attributes)) .catch(console.error); } catch (error) { // NOT working console.log('[ERROR]:', error); } // NOT working console.log('[FINISH] call end'); } async function handleEventRecord(record) { console.log(record.eventID); console.log(record.eventName); try { // after EmployeeInfo is created by the admin if (record.eventName === 'INSERT') { const arn = record.eventSourceARN; console.log(`[INSERT][${arn}]: ${JSON.stringify(record)}`); if (arn.includes(':table/EmployeeInfo')) { const dynamoId = record.dynamodb.NewImage.id['S']; const employeeId = record.dynamodb.NewImage.employeeId['S']; await handleNewEmployeeInfo(dynamoId, employeeId); } } } catch (error) { console.log('[ERROR]:', error); } } /** * @type {import('@types/aws-lambda').APIGatewayProxyHandler} */ exports.handler = async (event) => { console.log(`EVENT: ${JSON.stringify(event)}`); event.Records.forEach(async (record) => { await handleEventRecord(record); }); return Promise.resolve('Successfully processed DynamoDB record'); };
问题根源与修复方案
1. 异步错误捕获逻辑冲突
handleNewEmployeeInfo中混合使用await和.then()/.catch(),导致try/catch无法捕获DynamoDB操作的异常。.catch()已经内部捕获异常并打印,但未重新抛出,外层try/catch无法感知;若.catch()执行出错(比如日志输出异常),会直接导致Lambda进程崩溃。
修复代码:
async function handleNewEmployeeInfo(dynamoId, employeeId) { console.log( `[handleNewEmployeeInfo] begin. dynamoId(${dynamoId}) employeeId(${employeeId})` ); try { const employeeName = "TestString"; console.log( 'try to update table:', process.env.API_SCHOLARGRAPH_EMPLOYEEINFOTABLE_NAME, dynamoId, employeeName ); // 统一用try/catch处理,去掉.then/.catch const data = await dynamoDB.update({ TableName: process.env.API_SCHOLARGRAPH_EMPLOYEEINFOTABLE_NAME, Key: { id: dynamoId }, UpdateExpression: `set employeeName = :employeeName`, ExpressionAttributeValues: { ':employeeName': employeeName } }).promise(); console.log(data.Attributes); } catch (error) { console.log('[ERROR]:', error); } console.log('[FINISH] call end'); }
2. Lambda Handler未等待异步任务完成
exports.handler中使用forEach遍历异步函数,forEach不会等待异步操作执行完毕,Lambda会提前返回并终止进程,导致后续日志和代码逻辑无法执行。
修复代码:
exports.handler = async (event) => { console.log(`EVENT: ${JSON.stringify(event)}`); // 用Promise.all等待所有异步处理完成 await Promise.all(event.Records.map(async (record) => { await handleEventRecord(record); })); return 'Successfully processed DynamoDB record'; };
3. 额外检查项
- IAM权限验证:确认Lambda执行角色拥有目标DynamoDB表的
dynamodb:UpdateItem权限 - 数据类型匹配:检查
dynamoId的类型是否与表中id字段类型一致(比如表中是字符串类型,需确保获取的S值格式正确) - 记录存在性:如果更新的记录不存在,默认会抛出
ConditionalCheckFailedException,需根据业务需求添加ConditionExpression或处理该异常
内容的提问来源于stack exchange,提问作者Ning
相关产品推荐
相关产品推荐

