AWS DynamoDB не возвращает ответ на лямбда-функцию - PullRequest
1 голос
/ 07 января 2020

Я работаю с сервером и NodeJS, используя модуль aws -sdk, и я получаю 502 internal server error во внешнем интерфейсе приложения, ранее это отображалось как ошибка cors, но пока это так та же проблема только в одной указанной таблице c при выполнении обновления или удаления. Вот сама лямбда-функция:

export async function createUserSegment(event, context, callback) {
  const { data, timestamp, identityId } = extractRequestData(event)
  console.log('data', JSON.stringify(data));
  if (!verifyParamsExist(callback, ["Data", "IdentityId"], [data, identityId]) ||
    !verifyParamsExist(callback, ["Name", "Pattern", "Type"], [data.name, data.type, data.pattern]) ||
    !verifyValidParams(callback, [data.name, ...data.pattern], ["Name", "Pattern"], [{ value: data.type, enums: USER_SEGMENT_TYPES }], ["Type"])) {
      console.log('no good params');
    return false
  }

  let cleanedParams
  let params

  try {
    cleanedParams = cleanUserSegment(data.pattern, data.type)
    console.log('cleaned params', cleanedParams);
  } catch (e) {
    console.error(e)
    callback(null, badRequest({ type: "InvalidRule", status: false, msg: e.message }));
    return
  }

  params = {
    TableName: process.env.USER_SEGMENT_TABLE,
    Key: {
      "cognitoUsername": fetchSubFromEvent(event),
      "segmentName": data.name.trim(),
    },
    // Performs an insert (fails if already exists)
    // - 'cognitoUsername': cognito username (NOT IDENTITY ID!) of the segment creator.
    // - 'segmentName': user-provided name to identify the segment
    // - 'createdAt': unix timestamp for when segment is created
    // - 'pattern': user-supplied pattern that the segment refers to
    // - 'segmentType': either VISITED, NOT_VISITED, GOAL, NOT_GOAL to indicate what our pattern is matching (URL visits or goal completion)
    // - 'identityId': cognito identity id of the segment creator.  necessary for querying ES
    UpdateExpression: 'SET pattern = :pattern, segmentType = :segmentType, createdAt = :createdAt, identityId = :identityId',
    ConditionExpression: 'attribute_not_exists(cognitoUsername)',
    ExpressionAttributeValues: {
      ":pattern": cleanedParams.pattern,
      ":segmentType": cleanedParams.type,
      ":createdAt": timestamp,
      ":identityId": identityId,
    },
    ReturnValues: "ALL_NEW"
  };


  writeToDynamoAndCatchDuplicates(params, callback, transformUserSegment)

}

async function writeToDynamoAndCatchDuplicates(params, callback, transformFn){
  try {
    if(params.ConditionExpression){
      console.log(params);
    let result = await dynamoDbLib.call("update", params);
    console.log('this is res',result);
    result.Attributes = transformFn(result.Attributes)

    callback(null, success({ status: true, result: result }));
    } else {
      await dynamoDbLib.call("update", params);

      const paramsForAll = {
        TableName: params.TableName,
        KeyConditionExpression: "#cognitoUsername = :username",
        ExpressionAttributeNames: {
          "#cognitoUsername": "cognitoUsername",
        },
        ExpressionAttributeValues: {
          ":username": params.Key.cognitoUsername
        },
      }

      try {
        let result = await dynamoDbLib.call("query", paramsForAll);
        result.Items = result.Items.map(transformFn)
        console.log(result);

        callback(null, success({ status: true, result: result}));
      } catch (e) {
        console.error(e)
        callback(null, failure({ status: false }));
      }
    }
  } catch (e) {
    console.error(e)

    if(e.code === 'ConditionalCheckFailedException'){
      callback(null, badRequest({ type: "Duplicate", status: false }));
    } else {
      callback(null, failure({ status: false }));
    }
  }
}

Функция call для dynamoDbLib просто:

import AWS from "aws-sdk";

AWS.config.update({ region: "us-east-1" });

export function call(action, params) {
  const dynamoDb = new AWS.DynamoDB.DocumentClient();

  return dynamoDb[action](params).promise();
}

Запрос проходит через лямбду вплоть до writeToDynamoAndCatchDuplicates call функция выполнена. он отправляется на динамо, но никогда не возвращается, ни по таймауту, ни по ошибке, он просто заканчивается. В cloudwatch последнее, что я вижу, это журнал параметров от writeToDynamoAndCatchDuplicates, без ошибок. Я не изменил политики IAM для роли, назначенной всем лямбдам, со следующими разрешениями для вышеупомянутой таблицы:

...},
          {
            "Action": [
              "dynamodb:UpdateItem",
              "dynamodb:Query",
              "dynamodb:Scan",
              "dynamodb:DeleteItem"
            ],
            "Resource": [
              "arn:aws:dynamodb:us-east-1:xxxxxxxxxxxxx:table/staging-userSegmentTable"
            ],
            "Effect": "Allow"
          }, 
    { ...

Если кто-нибудь обнаружит что-либо, что может быть причиной проблемы, это будет высоко ценится.


Также вот последний журнал, показанный перед сообщением END для событий LOG:

2020-01-07T23:42:03.715Z    4fbf0957-c8be-4520-8277-7b9a9bda8b67    INFO    { TableName: 'staging-userSegmentTable',
  Key:
   { cognitoUsername: '*******************************',
     segmentName: 'cssfs' },
  UpdateExpression:
   'SET pattern = :pattern, segmentType = :segmentType, createdAt = :createdAt, identityId = :identityId',
  ConditionExpression: 'attribute_not_exists(cognitoUsername)',
  ExpressionAttributeValues:
   { ':pattern': [ '/' ],
     ':segmentType': [ 'CONTAINS' ],
     ':createdAt': 1578440523709,
     ':identityId': '****************************************' },
  ReturnValues: 'ALL_NEW' }

, что соответствует console.log(params) перед отправкой в ​​DynamoDB внутри оператора if функции writeToDynamoAndCatchDuplicates.

1 Ответ

0 голосов
/ 07 января 2020

Имеет ли ваш IAM доступ для чтения и записи к этой базе данных и группе безопасности, подключенной к экземпляру? Является ли это единственной таблицей, которая, по-видимому, является проблемой?

У меня была похожая проблема, в результате которой мне пришлось предоставить экземпляру БД полный доступ на чтение.

...