From 2e9fca89e327b9b680b20a6105088f0e844eb54a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominique=20J=C3=A4ggi?= <1872195+solaris007@users.noreply.github.com> Date: Wed, 15 Jan 2025 07:53:30 +0100 Subject: [PATCH] fix: improve sqs event adapter error handling (#541) This is to prevent ops alerts when no messages are in the payload. --- packages/spacecat-shared-utils/src/sqs.js | 40 +++++++++++-------- .../spacecat-shared-utils/test/sqs.test.js | 22 ++++++++++ 2 files changed, 46 insertions(+), 16 deletions(-) diff --git a/packages/spacecat-shared-utils/src/sqs.js b/packages/spacecat-shared-utils/src/sqs.js index bae8fdb9..532a9ab7 100644 --- a/packages/spacecat-shared-utils/src/sqs.js +++ b/packages/spacecat-shared-utils/src/sqs.js @@ -12,7 +12,15 @@ import { SendMessageCommand, SQSClient } from '@aws-sdk/client-sqs'; import AWSXray from 'aws-xray-sdk'; -import { hasText } from './functions.js'; + +import { hasText, isNonEmptyArray } from './functions.js'; + +function badRequest(message) { + return new Response('', { + status: 400, + headers: { 'x-error': message }, + }); +} /** * @class SQS utility to send messages to SQS @@ -94,24 +102,24 @@ export function sqsEventAdapter(fn) { const { log } = context; let message; + // currently not processing batch messages + const records = context.invocation?.event?.Records; + + if (!isNonEmptyArray(records)) { + log.warn('Function was not invoked properly, event does not contain any records'); + return badRequest('Event does not contain any records'); + } + + const record = records[0]; + + log.info(`Received ${records.length} records. ID of the first message in the batch: ${record.messageId}`); + try { - // currently not publishing batch messages - const records = context.invocation?.event?.Records; - if (!Array.isArray(records) || records.length === 0) { - throw new Error('No records found'); - } - - log.info(`Received ${records.length} records. ID of the first message in the batch: ${records[0]?.messageId}`); - message = JSON.parse(records[0]?.body); - log.info(`Received message with id: ${records[0]?.messageId}`); + message = JSON.parse(record.body); + log.info(`Received message with id: ${record.messageId}`); } catch (e) { log.warn('Function was not invoked properly, message body is not a valid JSON', e); - return new Response('', { - status: 400, - headers: { - 'x-error': 'Event does not contain a valid message body', - }, - }); + return badRequest('Event does not contain a valid message body'); } return fn(message, context); }; diff --git a/packages/spacecat-shared-utils/test/sqs.test.js b/packages/spacecat-shared-utils/test/sqs.test.js index 066bc69f..80d00544 100644 --- a/packages/spacecat-shared-utils/test/sqs.test.js +++ b/packages/spacecat-shared-utils/test/sqs.test.js @@ -147,6 +147,28 @@ describe('SQS', () => { const handler = sqsEventAdapter(exampleHandler); const response = await handler(emptyRequest, contextNoRecords); + expect(response.status).to.equal(400); + expect(response.headers.get('x-error')).to.equal('Event does not contain any records'); + }); + + it('returns bad request when record is not valid JSON', async () => { + const ctx = { + log: console, + invocation: { + event: { + Records: [ + { + body: 'not a valid JSON', + messageId: 'abcd', + }, + ], + }, + }, + }; + + const handler = sqsEventAdapter(exampleHandler); + const response = await handler(emptyRequest, ctx); + expect(response.status).to.equal(400); expect(response.headers.get('x-error')).to.equal('Event does not contain a valid message body'); });