diff --git a/infrastructure/modules/eventpub/lambda/eventpub/src/__tests__/index.test.js b/infrastructure/modules/eventpub/lambda/eventpub/src/__tests__/index.test.js index e11f735..5abfa3e 100644 --- a/infrastructure/modules/eventpub/lambda/eventpub/src/__tests__/index.test.js +++ b/infrastructure/modules/eventpub/lambda/eventpub/src/__tests__/index.test.js @@ -10,7 +10,8 @@ const validCloudEvent = { id: "123e4567-e89b-12d3-a456-426614174000", source: "mock", specversion: "1.0", - type: "data", + type: "uk.nhs.notify.supplier-api.letter.ACCEPTED.v1", + plane: "data", subject: "123e4567-e89b-12d3-a456-426614174001", time: "2024-01-01T00:00:00Z", datacontenttype: "application/json", diff --git a/infrastructure/modules/eventpub/lambda/eventpub/src/index.js b/infrastructure/modules/eventpub/lambda/eventpub/src/index.js index d0cfc8a..7e13462 100644 --- a/infrastructure/modules/eventpub/lambda/eventpub/src/index.js +++ b/infrastructure/modules/eventpub/lambda/eventpub/src/index.js @@ -27,7 +27,10 @@ function validateEvent(event) { 'data' ]; // Check top-level required fields - if (!requiredFields.every(field => event.hasOwnProperty(field))) { + const missingFields = requiredFields.filter(field => !event.hasOwnProperty(field)); + + if (missingFields.length > 0) { + console.error(`Event validation failed. Missing required fields: ${missingFields.join(', ')}. EventID: ${event.id || 'unknown'}, EventType: ${event.type || 'unknown'}`); return false; } return true; @@ -54,19 +57,20 @@ async function sendToEventBridge(events, eventBusArn) { const response = await eventBridge.send(new PutEventsCommand({ Entries: entries })); response.FailedEntryCount && response.Entries.forEach((entry, idx) => { if (entry.ErrorCode) { - console.warn(`Event failed with error: ${entry.ErrorCode}`); + console.error(`Event failed to send to EventBridge. ErrorCode: ${entry.ErrorCode}, ErrorMessage: ${entry.ErrorMessage}, EventID: ${batch[idx].id}, EventType: ${batch[idx].type}`); failedEvents.push(batch[idx]); } }); break; } catch (error) { - console.error(`EventBridge send error: ${error}`); + console.error(`EventBridge send error: ${error.name}, Message: ${error.message}, Code: ${error.$metadata?.httpStatusCode}, RequestId: ${error.$metadata?.requestId}`); if (error.retryable) { console.warn(`Retrying after backoff: attempt ${attempts + 1}`); await new Promise(res => setTimeout(res, 2 ** attempts * 100)); attempts++; } else { + console.error(`Non-retryable error encountered. Moving ${batch.length} events to DLQ`); failedEvents.push(...batch); break; } @@ -77,9 +81,17 @@ async function sendToEventBridge(events, eventBusArn) { } async function sendToDLQ(events) { + if (events.length === 0) return; + + console.warn(`Sending ${events.length} failed event(s) to DLQ: ${DLQ_URL}`); + for (const event of events) { - console.warn(`Sending ${events.length} failed events to DLQ`); - await sqs.send(new SendMessageCommand({ QueueUrl: DLQ_URL, MessageBody: JSON.stringify(event) })); + try { + await sqs.send(new SendMessageCommand({ QueueUrl: DLQ_URL, MessageBody: JSON.stringify(event) })); + console.debug(`Successfully sent event ${event.id} to DLQ`); + } catch (error) { + console.error(`Failed to send event ${event.id} to DLQ - Name: ${error.name}, Message: ${error.message}, Code: ${error.$metadata?.httpStatusCode}, RequestId: ${error.$metadata?.requestId}`); + } } } @@ -96,8 +108,10 @@ exports.handler = async (snsEvent) => { const invalidEvents = records.filter(event => !validateEvent(event)); console.debug(`Valid events: ${validEvents.length}, Invalid events: ${invalidEvents.length}`); - - if (invalidEvents.length) await sendToDLQ(invalidEvents); + if (invalidEvents.length) { + console.warn(`${invalidEvents.length} event(s) failed validation and will be sent to DLQ`); + await sendToDLQ(invalidEvents); + } const dataEvents = validEvents.filter(event => event.plane === 'data'); const controlEvents = validEvents.filter(event => event.plane === 'control'); diff --git a/infrastructure/modules/sqs/sqs_queue_policy.tf b/infrastructure/modules/sqs/sqs_queue_policy.tf index 43e5108..e9ad7cf 100644 --- a/infrastructure/modules/sqs/sqs_queue_policy.tf +++ b/infrastructure/modules/sqs/sqs_queue_policy.tf @@ -2,4 +2,3 @@ resource "aws_sqs_queue_policy" "sqs_queue_policy" { queue_url = aws_sqs_queue.sqs_queue.id policy = data.aws_iam_policy_document.sqs_queue.json } - diff --git a/scripts/config/pre-commit.yaml b/scripts/config/pre-commit.yaml index 29397e2..9c5e690 100644 --- a/scripts/config/pre-commit.yaml +++ b/scripts/config/pre-commit.yaml @@ -13,6 +13,7 @@ repos: - id: mixed-line-ending - id: pretty-format-json args: ['--autofix'] + exclude: '(^|/)package(-lock)?\.json$' # - id: ... - repo: local hooks: