I am writing a function to move three related items from their table to another using DynamoDB Transaction. I am writing the code in TypeScript with the SDK version 2.991.0 basically following this example code from the documentation: https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB/DocumentClient.html#transactWrite-property
The Problem is that documentclient.transactWrite does terminate without throwing an error, it doesn't pass an error to the callback function and the response object also has no error. However, the whole transaction fails without performing the delete or put instructions.
I verified that all the item keys exist and that the lambda has all the necessary permissions, but even if the items didn't exist or the permissions were missing I'd expect an error to be thrown.
This is the relevant part of my code:
const {
TABLE_NAME1, TABLE_NAME2, TABLE_NAME3, TABLE_NAME4, TABLE_NAME5, TABLE_NAME6, TABLE_NAME7, TABLE_NAME8,
} = process.env
const getMoveItemInput = (
fromTableName: string,
toTableName: string,
Key: Record<string, string | number>,
Item: any
) => [
{ Delete: { TableName: fromTableName, Key } },
{
Put: {
TableName: toTable,
Item,
},
},
]
export const handler = async (event) => {
const client = new DocumentClient({ convertEmptyValues: true })
const { itemId, removeFromBill } = event.arguments
/* Get userInfo, the item, orders and so on from DynamoDB + some verification
the following variables are read from the DB: itemBillingInfo, userId, item, orders, gifts
*/
const transactionItemDeleteBillingInfo = {
Delete: {
TableName: TABLE_NAME2!,
Key: {
hashKey: itemBillingInfo?.hashKey,
sortKey: itemBillingInfo?.sortKey,
},
},
}
const transactionItemMoveItem = getMoveItemInput(
TABLE_NAME1!,
TABLE_NAME6!,
{ userId, itemId },
item
)
const transactionItemMoveOrders = orders.map((order) =>
getMoveItemInput(
TABLE_NAME5!,
TABLE_NAME8!,
{ userId: order.userId, orderId: order.orderId },
order
)
)
const transactionItemMoveGifts = gifts.map((gift) =>
getMoveItemInput(
TABLE_NAME4!,
TABLE_NAME7!,
{ userId: gift.userId, orderId: gift.orderId },
giftOrder
)
)
const transactionInput = {
TransactItems: [
...transactionItemMoveItem,
...transactionItemMoveOrders.flat(),
...transactionItemMoveGifts.flat(),
...(removeFromBill && itemBillingInfo ? [transactionItemDeleteBillingInfo] : []),
],
}
console.log(JSON.stringify(transactionInput, null, 2))
const response = client.transactWrite(transactionInput, (error) => {
if (error) {
console.log(error)
}
})
console.log(response)
return true
}
If there is no order associated with the item it works as intended, but I am looking for an answer as to why there is no error thrown and no error passed to the callback.
Thanks for reading.
In the documentation it says "Synchronous write operation that groups up to 100 action requests." and the java docs comment form the node package is "Synchronous write operation that groups up to 25 action requests.". I tried
const response = await client.transactWrite(...)
, but that also doesn't work (and my IDE also tells me that client.transactWrite is synchronous)Its not clear which version of the SDK you use, as your client doesn't align with the proper import syntax. But I can make an assumption is V2, in which case you must await a promise. I suggest researching a little more on async/await programming with JS. Try
await client.transactWrite(...).promise()