I'm getting a 500 Internal Error
when trying to perform an update using an UpdateExpression
using the Node.js AWS SDK (AWS.DynamoDB.DocumentClient
).
The operation hangs for about 30 seconds and then returns this error:
InternalFailure: null
at Request.extractError (WORKSPACE/node_modules/aws-sdk/lib/protocol/json.js:52:27)
at Request.callListeners (WORKSPACE/node_modules/aws-sdk/lib/sequential_executor.js:106:20)
at Request.emit (WORKSPACE/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
at Request.emit (WORKSPACE/node_modules/aws-sdk/lib/request.js:688:14)
at Request.transition (WORKSPACE/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (WORKSPACE/node_modules/aws-sdk/lib/state_machine.js:14:12)
at WORKSPACE/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request.<anonymous> (WORKSPACE/node_modules/aws-sdk/lib/request.js:38:9)
at Request.<anonymous> (WORKSPACE/node_modules/aws-sdk/lib/request.js:690:12)
at Request.callListeners (WORKSPACE/node_modules/aws-sdk/lib/sequential_executor.js:116:18) {
code: 'InternalFailure',
time: 2021-10-08T16:24:49.756Z,
requestId: 'EJJH7IIRFCS0HOPNQ9IIS39CKJVV4KQNSO5AEMVJF66Q9ASUAAJG',
statusCode: 500,
retryable: true
}
I get this both when running my code in a Lambda function as well as when running locally using the DynamoDB REST API (so it's not a Lambda permission issue).
What's causing this internal error?
My code to update the item:
export async function addOverride(addOverrideRequest: any) {
const addListIfNotExists = {
TableName: addOverrideRequest.table,
Key: {
Environment: addOverrideRequest.environment
},
UpdateExpression: "SET Overrides.:overrideAttr = :emptylist",
ConditionExpression: "attribute_not_exists(Overrides.:overrideAttr)",
ExpressionAttributeValues: {
":overrideAttr": addOverrideRequest.overrideField,
":emptylist": [],
},
}
try {
const result = await DOCUMENT_CLIENT.update(addListIfNotExists).promise();
} catch (error) {
throw error;
}
}
The request resolves as:
{
TableName: 'AppVersions',
Key: { Environment: 'int' },
UpdateExpression: 'SET Overrides.:overrideAttr = :emptylist',
ConditionExpression: 'attribute_not_exists(Overrides.:overrideAttr)',
ExpressionAttributeValues: { ':overrideAttr': 'EyeTrackerType', ':emptylist': [] }
}
CodePudding user response:
While you can update attributes of a nested map, you can't define the attribute name itself dynamically in your request.
This means that your UpdateExpression
, ConditionExpression
& ExpressionAttributeValues
need to have the attribute name hardcoded, which is EyeTrackerType
in this case.
This should work:
const addListIfNotExists = {
TableName: addOverrideRequest.table,
Key: {
Environment: addOverrideRequest.environment
},
UpdateExpression: "SET Overrides.EyeTrackerType = :emptylist",
ConditionExpression: "attribute_not_exists(Overrides.EyeTrackerType)",
ExpressionAttributeValues: {
":emptylist": []
}
}
To keep it dynamic, I would create the UpdateExpression
& ConditionExpression
based on your business logic before passing it to AWS.