aws-sdk-js-v3: String values in ExpressionAttributeValue do not support emoji

Describe the bug

When the string value in ExpressionAttributeValues contains emoji, UpdateCommand and PutCommand can’t save data normally.

Your environment

SDK version number

@aws-sdk/lib-dynamodb@3.17.0

Is the issue in the browser/Node.js/ReactNative?

Browser

Details of the browser/Node.js/ReactNative version

Chrome: 100.0.4896.127

Steps to reproduce


function initDynamoDBClient() {
  dynamoDBClient = new DynamoDBClient({
    region: "ap-east-1",
    credentials: {
      accessKeyId: AWSAccessKeyId,
      secretAccessKey: AWSSecretAccessKey,
    },
    endpoint: "https://dynamodb.ap-east-1.amazonaws.com",
  });
  const marshallOptions = {
    convertEmptyValues: false,
    removeUndefinedValues: false,
    convertClassInstanceToMap: false
  };
  const unmarshallOptions = {
    wrapNumbers: false
  };
  const translateConfig = { marshallOptions, unmarshallOptions };
  ddbDocClient = DynamoDBDocumentClient.from(dynamoDBClient, translateConfig);
  console.log("initDynamoDBClient finished");
}

async function updateHistoryItem(item) {
  const params = {
    TableName: tbName,
    Key: {
      url: item.url,
    },
    ExpressionAttributeValues: {
      ":read_state": item.read_state || 0,
      ":title": item.title,   //title is a string , include emoji.
    },
    UpdateExpression: `SET 
    title = :title,
    read_state = :read_state`,
  };
  return updateItemFromDynamoDB(params);
}

async function updateItemFromDynamoDB(params) {
  return sendCommandToDynamoDB(new UpdateCommand(params));
}

async function putItemFromDynamoDB(params) {
  return sendCommandToDynamoDB(new PutCommand(params));
}

async function sendCommandToDynamoDB(command) {
  try {
    const data = await ddbDocClient.send(command);
    console.log("AWS DynamoDB send command -- succeeded");
    return data;
  } catch (err) {    
    console.error(
      "AWS DynamoDB send command -- failed:" + "\n" + JSON.stringify(err)
    );
    return null;
  }
}

Observed behavior

Exception was thrown

failed: {"__type":"com.amazon.coral.service#InvalidSignatureException","name":"InvalidSignatureException","$fault":"client","$metadata":{"httpStatusCode":400,"requestId":"ML8R85HMGCI4FL4KQA4NKHPG5VVV4KQNSO5AEMVJF66Q9ASUAAJG","attempts":3,"totalRetryDelay":477}}

InvalidSignatureException: The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.

Expected behavior

The string value containing the emoji was successfully saved or provide a function for encoding.

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 1
  • Comments: 15 (9 by maintainers)

Most upvoted comments

It appears to be an issue with Content-Length in the browser request.

Here is a patch file with a middleware which prints headers put-item-with-emoji-and-middleware.txt

With the text Hello World!, here is the diff between Node.js and browser

string no emoji diff

string-no-emoji-diff

Rename .txt to .html to view after download: string-no-emoji-diff.txt

With the text Hello World!😄 the content-length in Node.js is 73, while that in browser is 75.

string with emoji diff

string-emoji-diff

Rename .txt to .html to view after download: string-emoji-diff.txt