Есть таблица DynamoDB под названием Portal.
Из функции Lambda, записанной в узле, я хочу обновить поля status и ts элемента (путем вызова функции signalJobStart) и дождаться завершения функции асинхронного обновления с обещанием, прежде чем продолжить.
По какой-то причине обновление не происходит, однако во время работы ошибок не возникает.
В журналах нет ошибок, и я вижу в журналах сообщение «ЗАВЕРШЕНО».
Почему в элементе таблицы нет изменений? Почему я не вижу ни ошибки, ни сообщения об успехе в журналах?
(Я также пробовал без обещания, с тем же результатом. Элемент таблицы не обновляется - даже асинхронно.)
Вот код из лямбды:
const AWS = require('aws-sdk');
const docClient = new AWS.DynamoDB.DocumentClient({region: 'eu-west-1'});
module.exports = {
signalJobStart: function(accountId, jobId) {
console.info("Signaling job start for account %s and job %s", accountId, jobId);
let table = "Portal";
let params = {
TableName: table,
Key:{
"accountid": accountId,
"entity": jobId
},
UpdateExpression: "SET status = :s, ts = :t",
ExpressionAttributeValues:{
":s": "running",
":t": Date.now()
},
ReturnValues:"UPDATED_NEW"
};
let updatePromise = docClient.update(params, function(err, data) {
if (err) {
console.error("Unable to update item. Error JSON:", JSON.stringify(err, null, 2));
} else {
console.info("UpdateItem succeeded:", JSON.stringify(data, null, 2));
}
}).promise();
updatePromise.then(function(data) {
console.info('Success');
}).catch(function(err) {
console.info(err);
});
console.info("FINISHED");
}};





Я думаю ты мог бы
docClient.update(params).promise()
а затем продолжайте использовать поток операторов .then(...), чтобы заставить его работать.
Лично я думаю, что синтаксис обработчика ошибок (для update) может не дать вам обещания.
Сообщите мне, если это не сработает.
можете ли вы подтвердить, что в этом новом синтаксисе updatePromise НЕ является обещанием?
Это действительно хорошая зацепка. Я только что проверил, и это обещание, выход из системы как Promise { <pending> }, хотя у меня есть подозрение на то, что он ожидает и истекает время ожидания?
В вашем запросе status - это зарезервировать ключевые слова и запрещен в динамодб. Так что используйте ExpressionAttributeNames в своем запросе.
Also use new Promise for handle promise
Пожалуйста, проверьте ниже, как он вам поможет:
module.exports = {
signalJobStart: function (accountId, jobId) {
return new Promise(function (resolve, reject) {
console.info("Signaling job start for account %s and job %s", accountId, jobId);
let table = "Portal";
let params = {
TableName: table,
Key: {
"accountid": accountId,
"entity": jobId
},
UpdateExpression: "SET #status = :s, ts = :t",
ExpressionAttributeNames: {
'#status': 'status'
},
ExpressionAttributeValues: {
":s": "running",
":t": Date.now()
},
ReturnValues: "UPDATED_NEW"
};
docClient.update(params, function (err, data) {
if (err) {
console.error("Unable to update item. Error JSON:", JSON.stringify(err, null, 2));
reject(err)
} else {
console.info("UpdateItem succeeded:", JSON.stringify(data, null, 2));
resolve({ message: 'sucsss', data: data })
}
})
});
}
};
Note: Please also confirm
accountidandentityare bothKeyin you DB.
Изменено, как вы предложили, все еще безуспешно. accountid - это ключ первичного раздела, а entity - первичный ключ сортировки в таблице.
Ошибка не возникает. Лямбда-функция просто завершается в обычном режиме. Последний ЗАВЕРШЕННЫЙ комментарий выводится из системы. Расскажите подробнее о use new Promise.
Когда вы печатаете console.info("FINISHED");, сначала он печатает, потому что он асинхронный, поэтому не нужно ждать обновления. вы можете проверить, какой отпечаток после этого.
Дальше ничего нет, просто доделываем лямбду. Похоже, асинхронный вызов ожидает и, возможно, не завершен. Просто я не уверен, почему нет ошибки по таймауту.
Можете ли вы попробовать заменить старый код на мой новый?
Позвольте нам продолжить обсуждение в чате.
Что помогло в моем случае:
Выполните async / await способом:
exports.handler = async (event) => {
...
let _result = "";
try {
_result = await docClient.update(_updateParams).promise();
} catch(ex){
_result = ex;
}
..
Убедитесь, что поле, в которое я писал, не является зарезервированным словом, как в следующем случае («данные» - зарезервированное слово):
{
..
UpdateExpression: "set data = :newdata",
ExpressionAttributeValues: {
":newdata": "blah"
},
..
Чтобы проверить это: переименуйте столбец, скажем, в «data2» - это сработало без проблем.
Убедитесь, что у вас есть разрешения в «Роль выполнения» в IAM Console.
Раньше я также пробовал это с опущением обработчика ошибок с тем же (нет) результатом. Теперь удалил снова, все еще безуспешно. Просто изменился на этот: let updatePromise = docClient.update (params) .promise ();