Bug: SnsSqsEnvelope does not parse `Message` as JSON
Closed this issue · 4 comments
Expected Behavior
Using SnsSqsEnvelope should parse a JSON body in the Message field.
Current Behavior
Currently, the parser will crash out with the following error:
ParseError: Failed to parse SQS Record at index 0
Code snippet
import { SnsSqsEnvelope } from '@aws-lambda-powertools/parser/envelopes/sns-sqs';
import { z } from 'zod';
const person = z.object({
firstName: z.string(),
lastName: z.string(),
});
const sqsRecord = {
messageId: '059f36b4-87a3-44ab-83d2-661975830a7d',
receiptHandle: 'AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...',
attributes: {
ApproximateReceiveCount: '1',
SentTimestamp: '1545082649183',
SenderId: 'AIDAIENQZJOLO23YVJ4VO',
ApproximateFirstReceiveTimestamp: '1545082649185',
},
messageAttributes: {},
md5OfBody: 'e4e68fb7bd0e697a0ae8f1bb342846b3',
eventSource: 'aws:sqs',
eventSourceARN: 'arn:aws:sqs:eu-west-1:123456789012:my-queue',
awsRegion: 'eu-west-1',
body: JSON.stringify({
SignatureVersion: '1',
Timestamp: new Date().toISOString(),
Signature: 'EXAMPLEw6JR0u+X6pYkZf+QTTJvtuY=',
SigningCertUrl: 'https://sns.eu-west-1.amazonaws.com/SimpleNotificationService.pem',
MessageId: '95df01b4-ee98-5cb9-9903-4c221d41eb5e',
Message: JSON.stringify({
firstName: 'Bob',
lastName: 'Smith'
}),
MessageAttributes: {
Attribute1: {
Type: 'String',
Value: 'Value1',
},
},
UnsubscribeUrl: 'https://sns.eu-west-1.amazonaws.com/?Action=Unsubscribe',
TopicArn: 'arn:aws:sns:eu-west-1:123456789012:ExampleTopic',
Type: 'Notification',
}),
};
const sqsEvent = { Records: [sqsRecord] };
const people = SnsSqsEnvelope.parse(sqsEvent, person);
for (const person of people) {
console.log(`${person.firstName} ${person.lastName}`);
}Steps to Reproduce
mkdir repro
cd repro
npm init --yes
npm i @aws-lambda-powertools/parser zod
# paste snippet code into index.js
node index.jsPossible Solution
Update this code:
powertools-lambda-typescript/packages/parser/src/envelopes/sns-sqs.ts
Lines 71 to 73 in b92b0c6
To:
return schema.parse(
JSON.parse(SnsSqsNotificationSchema.parse(JSON.parse(record.body)).Message)
);Powertools for AWS Lambda (TypeScript) version
latest
AWS Lambda function runtime
22.x
Packaging format used
npm
Execution logs
Hi @ben-eb, thanks for opening this issue.
The envelope intentionally doesn't force JSON parsing because, in practice, SQS messages don't have to be JSON stringified objects but can also be plain text strings or strings with other types of encodings.
Because of this, when passing the schema for your payload, if you know that it's going to be JSON encoded you should use the JSONStringified helper which tells Zod to run JSON.parse before parsing.
Your example should add these lines:
import { JSONStringified } from '@aws-lambda-powertools/parser/helpers';
const people = SnsSqsEnvelope.parse(sqsEvent, JSONStringified(person));Many thanks, missed this in the docs. 👍
Warning
This issue is now closed. Please be mindful that future comments are hard for our team to see.
If you need more assistance, please either reopen the issue, or open a new issue referencing this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.
Warning
This issue is now closed. Please be mindful that future comments are hard for our team to see.
If you need more assistance, please either reopen the issue, or open a new issue referencing this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.