aws-sdk-js
aws-sdk-js copied to clipboard
Error is swallowed when MessageDeduplicationId is used in standard queue
Describe the bug
When I am sending a message to an SQS Queue that is not a FIFO queue and I use MessageDeduplicationId as one of the params, the error that is returned from AWS is not thrown. I had to do a lot of debugging in order to find out what the actual error was. I put a breakpoint here: https://github.com/aws/aws-sdk-js/blob/878c4d68979d2184a48cd49d1912ecfa7e8713d0/lib/event_listeners.js#L363
And I can see that the response is:
<?xml version=\"1.0\"?>
<SendMessageBatchResponse
xmlns=\"http://queue.amazonaws.com/doc/2012-11-05/\">
<SendMessageBatchResult>
<BatchResultErrorEntry>
<Id>ffffff-ffffff-ffffff-ffffff</Id>
<Code>InvalidParameterValue</Code>
<Message>The request include parameter that is not valid for this queue type</Message>
<SenderFault>true</SenderFault>
</BatchResultErrorEntry>
</SendMessageBatchResult>
<ResponseMetadata>
<RequestId>ffffff-ffffff-ffffff-ffffff-ffffff</RequestId>
</ResponseMetadata>
</SendMessageBatchResponse>"
But an error was never thrown, when using .promise() or listening on a callback.
Expected Behavior
An error would be thrown when an error is encountered
Current Behavior
The error is swallowed and never propagates outside of the AWS SDK
Reproduction Steps
const params = {
QueueUrl: "https://sqs.us-east-2.amazonaws.com/FFFFFFFFFF/SomeQueue",
Entries: [
{
Id: "FFFFFFFFFF-FFFFFFFFFF-FFFFFFFFFF",
MessageBody: "Some Message",
MessageAttributes: {
EnvironmentId: {
DataType: "String",
StringValue: "dev",
},
},
MessageDeduplicationId: "FFFFFFFFFF",
},
],
};
const sqs = new AWS.SQS({ region: 'us-east-2' });
try {
await sqs.sendMessageBatch(params).promise();
} catch (err) {
console.log('this is never triggered');
}
sqs.sendMessageBatch(params, (err, data) => {
console.log('This is never triggered either');
});
Possible Solution
No response
Additional Information/Context
No response
SDK version used
2.1222.0
Environment details (OS name and version, etc.)
MacOS, Node v14.18.0
Hi there - apologies for the long delay response.
The sendMessageBatch operation in SQS can return a partial success response. This means that even if some messages in the batch fail, the operation will still return a response with the successful message IDs and error details for the failed messages. However, SDK doesn't consider this a complete failure and hence, it doesn't throw an error in the promise or callback.
To handle this scenario, you need to check the response data for any error entries and handle them accordingly. Here's how you can modify your code:
const params = {
QueueUrl: "https://sqs.us-east-2.amazonaws.com/FFFFFFFFFF/SomeQueue",
Entries: [
{
Id: "FFFFFFFFFF-FFFFFFFFFF-FFFFFFFFFF",
MessageBody: "Some Message",
MessageAttributes: {
EnvironmentId: {
DataType: "String",
StringValue: "dev",
},
},
MessageDeduplicationId: "FFFFFFFFFF",
},
],
};
const sqs = new AWS.SQS({ region: 'us-east-2' });
// Using promise
sqs.sendMessageBatch(params).promise()
.then((data) => {
const errorEntries = data.Failed;
if (errorEntries && errorEntries.length > 0) {
const errors = errorEntries.map(entry => `Id: ${entry.Id}, Code: ${entry.Code}, Message: ${entry.Message}`);
throw new Error(`Errors occurred while sending messages: ${errors.join(', ')}`);
}
console.log('Messages sent successfully');
})
.catch(err => {
console.error('Error:', err);
});
// Using callback
sqs.sendMessageBatch(params, (err, data) => {
if (err) {
console.error('Error:', err);
} else {
const errorEntries = data.Failed;
if (errorEntries && errorEntries.length > 0) {
const errors = errorEntries.map(entry => `Id: ${entry.Id}, Code: ${entry.Code}, Message: ${entry.Message}`);
console.error(`Errors occurred while sending messages: ${errors.join(', ')}`);
} else {
console.log('Messages sent successfully');
}
}
});
In this modified code, we're checking the Failed property of the response data. If there are any failed messages, we're constructing an error message with the details of the failed messages and throwing a new Error in the promise chain or logging the error message in the callback.
By handling the errors this way, you'll be able to catch and handle the errors properly when using the sendMessageBatch operation with a non-FIFO queue and providing the MessageDeduplicationId parameter.
Hope that helps, John