Skip to content

Commit 96bd30d

Browse files
authored
Merge branch 'main' into 1776-json-replacer-fn
2 parents 87989e4 + 12f8e5f commit 96bd30d

19 files changed

+499
-90
lines changed

.github/workflows/codeql.yml

Lines changed: 0 additions & 51 deletions
This file was deleted.

.github/workflows/ossf_scorecard.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ jobs:
3535
# repo_token: ${{ secrets.SCORECARD_TOKEN }} # read-only fine-grained token to read branch protection settings
3636

3737
- name: "Upload results"
38-
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
38+
uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4
3939
with:
4040
name: SARIF file
4141
path: results.sarif

.github/workflows/publish_layer.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ jobs:
4545
- name: Zip output
4646
run: zip -r cdk.out.zip layers/cdk.out
4747
- name: Archive CDK artifacts
48-
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
48+
uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4
4949
with:
5050
name: cdk-layer-artifact
5151
path: cdk.out.zip
@@ -97,7 +97,7 @@ jobs:
9797
with:
9898
ref: ${{ github.sha }}
9999
- name: Download CDK layer artifacts
100-
uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7
100+
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
101101
with:
102102
path: cdk-layer-stack
103103
pattern: cdk-layer-stack-* # merge all Layer artifacts created per region earlier (reusable_deploy_layer_stack.yml; step "Save Layer ARN artifact")

.github/workflows/record_pr.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ jobs:
5353
script: |
5454
const script = require('.github/scripts/save_pr_details.js')
5555
await script({github, context, core})
56-
- uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
56+
- uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4
5757
with:
5858
name: pr
5959
path: pr.txt

.github/workflows/reusable_deploy_layer_stack.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ jobs:
7878
- name: Setup dependencies
7979
uses: ./.github/actions/cached-node-modules
8080
- name: Download artifact
81-
uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7
81+
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
8282
with:
8383
name: ${{ inputs.artifact-name }}
8484
- name: Unzip artifact
@@ -93,7 +93,7 @@ jobs:
9393
cat cdk-layer-stack/${{ matrix.region }}-layer-version.txt
9494
- name: Save Layer ARN artifact
9595
if: ${{ inputs.stage == 'PROD' }}
96-
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
96+
uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4
9797
with:
9898
name: cdk-layer-stack-${{ matrix.region }}
9999
path: ./cdk-layer-stack/* # NOTE: upload-artifact does not inherit working-directory setting.

.github/workflows/reusable_publish_docs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ jobs:
9696
run: |
9797
cp -r api site/
9898
- name: Create Artifact (Site)
99-
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
99+
uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4
100100
with:
101101
name: site
102102
path: site

docs/utilities/batch.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ All records in the batch will be passed to this handler for processing, even if
261261

262262
* **All records successfully processed**. We will return an empty list of item failures `{'batchItemFailures': []}`
263263
* **Partial success with some exceptions**. We will return a list of all item IDs/sequence numbers that failed processing
264-
* **All records failed to be processed**. We will raise `BatchProcessingError` exception with a list of all exceptions raised when processing
264+
* **All records failed to be processed**. We will throw a `FullBatchFailureError` error with a list of all the errors thrown while processing unless `throwOnFullBatchFailure` is disabled.
265265

266266
The following sequence diagrams explain how each Batch processor behaves under different scenarios.
267267

@@ -450,6 +450,18 @@ We can automatically inject the [Lambda context](https://docs.aws.amazon.com/lam
450450
--8<-- "examples/snippets/batch/accessLambdaContext.ts"
451451
```
452452

453+
### Working with full batch failures
454+
455+
By default, the `BatchProcessor` will throw a `FullBatchFailureError` if all records in the batch fail to process, we do this to reflect the failure in your operational metrics.
456+
457+
When working with functions that handle batches with a small number of records, or when you use errors as a flow control mechanism, this behavior might not be desirable as your function might generate an unnaturally high number of errors. When this happens, the [Lambda service will scale down the concurrency of your function](https://docs.aws.amazon.com/lambda/latest/dg/services-sqs-errorhandling.html#services-sqs-backoff-strategy){target="_blank"}, potentially impacting performance.
458+
459+
For these scenarios, you can set the `throwOnFullBatchFailure` option to `false` when calling.
460+
461+
```typescript hl_lines="17"
462+
--8<-- "examples/snippets/batch/noThrowOnFullBatchFailure.ts"
463+
```
464+
453465
### Extending BatchProcessor
454466

455467
You might want to bring custom logic to the existing `BatchProcessor` to slightly override how we handle successes and failures.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import {
2+
BatchProcessor,
3+
EventType,
4+
processPartialResponse,
5+
} from '@aws-lambda-powertools/batch';
6+
import type { SQSHandler, SQSRecord } from 'aws-lambda';
7+
8+
const processor = new BatchProcessor(EventType.SQS);
9+
10+
const recordHandler = async (_record: SQSRecord): Promise<void> => {
11+
// Process the record
12+
};
13+
14+
export const handler: SQSHandler = async (event, context) =>
15+
processPartialResponse(event, recordHandler, processor, {
16+
context,
17+
throwOnFullBatchFailure: false,
18+
});

packages/batch/src/BasePartialBatchProcessor.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,8 @@ abstract class BasePartialBatchProcessor extends BasePartialProcessor {
6363
/**
6464
* Clean up logic to be run after processing a batch
6565
*
66-
* If the entire batch failed, and the utility is not configured otherwise,
67-
* this method will throw a `FullBatchFailureError` with the list of errors
68-
* that occurred during processing.
66+
* If the entire batch failed this method will throw a {@link FullBatchFailureError | `FullBatchFailureError`} with the list of
67+
* errors that occurred during processing, unless the `throwOnFullBatchFailure` option is set to `false`.
6968
*
7069
* Otherwise, it will build the partial failure response based on the event type.
7170
*/
@@ -74,7 +73,10 @@ abstract class BasePartialBatchProcessor extends BasePartialProcessor {
7473
return;
7574
}
7675

77-
if (this.entireBatchFailed()) {
76+
if (
77+
this.options?.throwOnFullBatchFailure !== false &&
78+
this.entireBatchFailed()
79+
) {
7880
throw new FullBatchFailureError(this.errors);
7981
}
8082

packages/batch/src/processPartialResponse.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,31 @@ import type {
4242
* });
4343
* ```
4444
*
45+
* By default, if the entire batch fails, the function will throw an error.
46+
* If you want to prevent this behavior, you can set the `throwOnFullBatchFailure` to `false`
47+
*
48+
* @example
49+
* ```typescript
50+
* import {
51+
* BatchProcessor,
52+
* EventType,
53+
* processPartialResponse,
54+
* } from '@aws-lambda-powertools/batch';
55+
* import type { KinesisStreamHandler, KinesisStreamRecord } from 'aws-lambda';
56+
*
57+
* const processor = new BatchProcessor(EventType.KinesisDataStreams);
58+
*
59+
* const recordHandler = async (record: KinesisStreamRecord): Promise<void> => {
60+
* const payload = JSON.parse(record.kinesis.data);
61+
* };
62+
*
63+
* export const handler: KinesisStreamHandler = async (event, context) =>
64+
* processPartialResponse(event, recordHandler, processor, {
65+
* context,
66+
* throwOnFullBatchFailure: false
67+
* });
68+
* ```
69+
*
4570
* @param event The event object containing the batch of records
4671
* @param recordHandler Async function to process each record from the batch
4772
* @param processor Batch processor instance to handle the batch processing

packages/batch/src/processPartialResponseSync.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,30 @@ import type {
6868
* });
6969
* ```
7070
*
71+
* By default, if the entire batch fails, the function will throw an error.
72+
* If you want to prevent this behavior, you can set the `throwOnFullBatchFailure` to `false`
73+
*
74+
* @example
75+
* ```typescript
76+
* import {
77+
* SqsFifoPartialProcessor,
78+
* processPartialResponseSync,
79+
* } from '@aws-lambda-powertools/batch';
80+
* import type { SQSRecord, SQSHandler } from 'aws-lambda';
81+
*
82+
* const processor = new SqsFifoPartialProcessor();
83+
*
84+
* const recordHandler = async (record: SQSRecord): Promise<void> => {
85+
* const payload = JSON.parse(record.body);
86+
* };
87+
*
88+
* export const handler: SQSHandler = async (event, context) =>
89+
* processPartialResponseSync(event, recordHandler, processor, {
90+
* context,
91+
* throwOnFullBatchFailure: false
92+
* });
93+
* ```
94+
*
7195
* @param event The event object containing the batch of records
7296
* @param recordHandler Sync function to process each record from the batch
7397
* @param processor Batch processor instance to handle the batch processing

packages/batch/src/types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { BasePartialBatchProcessor } from './BasePartialBatchProcessor.js';
1313
* @template T The type of the batch processor, defaults to BasePartialBatchProcessor
1414
* @property context The context object provided by the AWS Lambda runtime
1515
* @property skipGroupOnError The option to group on error during processing
16+
* @property throwOnFullBatchFailure The option to throw an error if the entire batch fails
1617
*/
1718
type BatchProcessingOptions<T = BasePartialBatchProcessor> = {
1819
/**
@@ -25,6 +26,10 @@ type BatchProcessingOptions<T = BasePartialBatchProcessor> = {
2526
* If true skip the group on error during processing.
2627
*/
2728
skipGroupOnError?: T extends SqsFifoPartialProcessor ? boolean : never;
29+
/**
30+
* Set this to false to prevent throwing an error if the entire batch fails.
31+
*/
32+
throwOnFullBatchFailure?: boolean;
2833
};
2934

3035
/**

0 commit comments

Comments
 (0)