Handling errors for an SQS event source in Lambda (original) (raw)

To handle errors related to an SQS event source, Lambda automatically uses a retry strategy with a backoff strategy. You can also customize error handling behavior by configuring your SQS event source mapping to return partial batch responses.

Backoff strategy for failed invocations

When an invocation fails, Lambda attempts to retry the invocation while implementing a backoff strategy. The backoff strategy differs slightly depending on whether Lambda encountered the failure due to an error in your function code, or due to throttling.

Implementing partial batch responses

When your Lambda function encounters an error while processing a batch, all messages in that batch become visible in the queue again by default, including messages that Lambda processed successfully. As a result, your function can end up processing the same message several times.

To avoid reprocessing successfully processed messages in a failed batch, you can configure your event source mapping to make only the failed messages visible again. This is called a partial batch response. To turn on partial batch responses, specify ReportBatchItemFailures for theFunctionResponseTypes action when configuring your event source mapping. This lets your function return a partial success, which can help reduce the number of unnecessary retries on records.

When ReportBatchItemFailures is activated, Lambda doesn't scale down message polling when function invocations fail. If you expect some messages to fail—and you don't want those failures to impact the message processing rate—use ReportBatchItemFailures.

Note

Keep the following in mind when using partial batch responses:

To activate partial batch reporting
  1. Review the Best practices for implementing partial batch responses.
  2. Run the following command to activate ReportBatchItemFailures for your function. To retrieve your event source mapping's UUID, run the list-event-source-mappings AWS CLI command.
aws lambda update-event-source-mapping \  
--uuid "a1b2c3d4-5678-90ab-cdef-11111EXAMPLE" \  
--function-response-types "ReportBatchItemFailures"  
  1. Update your function code to catch all exceptions and return failed messages in a batchItemFailures JSON response. The batchItemFailures response must include a list of message IDs, as itemIdentifier JSON values.
    For example, suppose you have a batch of five messages, with message IDs id1, id2, id3, id4, and id5. Your function successfully processes id1, id3, and id5. To make messages id2 and id4 visible again in your queue, your function should return the following response:
{  
  "batchItemFailures": [  
        {  
            "itemIdentifier": "id2"  
        },  
        {  
            "itemIdentifier": "id4"  
        }  
    ]  
}  

Here are some examples of function code that return the list of failed message IDs in the batch:
.NET
SDK for .NET

Note

There's more on GitHub. Find the complete example and learn how to set up and run in theServerless examples repository.
Reporting SQS batch item failures with Lambda using .NET.

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.  
// SPDX-License-Identifier: Apache-2.0  
using Amazon.Lambda.Core;  
using Amazon.Lambda.SQSEvents;  
// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.  
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]  
namespace sqsSample;  
public class Function  
{  
    public async Task<SQSBatchResponse> FunctionHandler(SQSEvent evnt, ILambdaContext context)  
    {  
        List<SQSBatchResponse.BatchItemFailure> batchItemFailures = new List<SQSBatchResponse.BatchItemFailure>();  
        foreach(var message in evnt.Records)  
        {  
            try  
            {  
                //process your message  
                await ProcessMessageAsync(message, context);  
            }  
            catch (System.Exception)  
            {  
                //Add failed message identifier to the batchItemFailures list  
                batchItemFailures.Add(new SQSBatchResponse.BatchItemFailure{ItemIdentifier=message.MessageId});  
            }  
        }  
        return new SQSBatchResponse(batchItemFailures);  
    }  
    private async Task ProcessMessageAsync(SQSEvent.SQSMessage message, ILambdaContext context)  
    {  
        if (String.IsNullOrEmpty(message.Body))  
        {  
            throw new Exception("No Body in SQS Message.");  
        }  
        context.Logger.LogInformation($"Processed message {message.Body}");  
        // TODO: Do interesting work based on the new message  
        await Task.CompletedTask;  
    }  
}  

Go
SDK for Go V2

Note

There's more on GitHub. Find the complete example and learn how to set up and run in theServerless examples repository.
Reporting SQS batch item failures with Lambda using Go.

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.  
// SPDX-License-Identifier: Apache-2.0  
package main  
import (  
    "context"  
    "encoding/json"  
    "fmt"  
    "github.com/aws/aws-lambda-go/events"  
    "github.com/aws/aws-lambda-go/lambda"  
)  
func handler(ctx context.Context, sqsEvent events.SQSEvent) (map[string]interface{}, error) {  
    batchItemFailures := []map[string]interface{}{}  
    for _, message := range sqsEvent.Records {  
          
        if /* Your message processing condition here */ {  
            batchItemFailures = append(batchItemFailures, map[string]interface{}{"itemIdentifier": message.MessageId})  
        }  
    }  
    sqsBatchResponse := map[string]interface{}{  
        "batchItemFailures": batchItemFailures,  
    }  
    return sqsBatchResponse, nil  
}  
func main() {  
    lambda.Start(handler)  
}  

Java
SDK for Java 2.x

Note

There's more on GitHub. Find the complete example and learn how to set up and run in theServerless examples repository.
Reporting SQS batch item failures with Lambda using Java.

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.  
// SPDX-License-Identifier: Apache-2.0  
import com.amazonaws.services.lambda.runtime.Context;  
import com.amazonaws.services.lambda.runtime.RequestHandler;  
import com.amazonaws.services.lambda.runtime.events.SQSEvent;  
import com.amazonaws.services.lambda.runtime.events.SQSBatchResponse;  
   
import java.util.ArrayList;  
import java.util.List;  
   
public class ProcessSQSMessageBatch implements RequestHandler<SQSEvent, SQSBatchResponse> {  
    @Override  
    public SQSBatchResponse handleRequest(SQSEvent sqsEvent, Context context) {  
   
         List<SQSBatchResponse.BatchItemFailure> batchItemFailures = new ArrayList<SQSBatchResponse.BatchItemFailure>();  
         String messageId = "";  
         for (SQSEvent.SQSMessage message : sqsEvent.getRecords()) {  
             try {  
                 //process your message  
             } catch (Exception e) {  
                 //Add failed message identifier to the batchItemFailures list  
                 batchItemFailures.add(new SQSBatchResponse.BatchItemFailure(message.getMessageId()));  
             }  
         }  
         return new SQSBatchResponse(batchItemFailures);  
     }  
}  

JavaScript
SDK for JavaScript (v3)

Note

There's more on GitHub. Find the complete example and learn how to set up and run in theServerless examples repository.
Reporting SQS batch item failures with Lambda using JavaScript.

// Node.js 20.x Lambda runtime, AWS SDK for Javascript V3  
export const handler = async (event, context) => {  
    const batchItemFailures = [];  
    for (const record of event.Records) {  
        try {  
            await processMessageAsync(record, context);  
        } catch (error) {  
            batchItemFailures.push({ itemIdentifier: record.messageId });  
        }  
    }  
    return { batchItemFailures };  
};  
async function processMessageAsync(record, context) {  
    if (record.body && record.body.includes("error")) {  
        throw new Error("There is an error in the SQS Message.");  
    }  
    console.log(`Processed message: ${record.body}`);  
}  

Reporting SQS batch item failures with Lambda using TypeScript.

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.  
// SPDX-License-Identifier: Apache-2.0  
import { SQSEvent, SQSBatchResponse, Context, SQSBatchItemFailure, SQSRecord } from 'aws-lambda';  
export const handler = async (event: SQSEvent, context: Context): Promise<SQSBatchResponse> => {  
    const batchItemFailures: SQSBatchItemFailure[] = [];  
    for (const record of event.Records) {  
        try {  
            await processMessageAsync(record);  
        } catch (error) {  
            batchItemFailures.push({ itemIdentifier: record.messageId });  
        }  
    }  
    return {batchItemFailures: batchItemFailures};  
};  
async function processMessageAsync(record: SQSRecord): Promise<void> {  
    if (record.body && record.body.includes("error")) {  
        throw new Error('There is an error in the SQS Message.');  
    }  
    console.log(`Processed message ${record.body}`);  
}  

PHP
SDK for PHP

Note

There's more on GitHub. Find the complete example and learn how to set up and run in theServerless examples repository.
Reporting SQS batch item failures with Lambda using PHP.

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.  
// SPDX-License-Identifier: Apache-2.0  
<?php  
use Bref\Context\Context;  
use Bref\Event\Sqs\SqsEvent;  
use Bref\Event\Sqs\SqsHandler;  
use Bref\Logger\StderrLogger;  
require __DIR__ . '/vendor/autoload.php';  
class Handler extends SqsHandler  
{  
    private StderrLogger $logger;  
    public function __construct(StderrLogger $logger)  
    {  
        <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>t</mi><mi>h</mi><mi>i</mi><mi>s</mi><mo>−</mo><mo>&gt;</mo><mi>l</mi><mi>o</mi><mi>g</mi><mi>g</mi><mi>e</mi><mi>r</mi><mo>=</mo></mrow><annotation encoding="application/x-tex">this-&gt;logger = </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7778em;vertical-align:-0.0833em;"></span><span class="mord mathnormal">t</span><span class="mord mathnormal">hi</span><span class="mord mathnormal">s</span><span class="mord">−</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">&gt;</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">o</span><span class="mord mathnormal" style="margin-right:0.03588em;">gg</span><span class="mord mathnormal" style="margin-right:0.02778em;">er</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span></span></span></span>logger;  
    }  
    /**  
     * @throws JsonException  
     * @throws \Bref\Event\InvalidLambdaEvent  
     */  
    public function handleSqs(SqsEvent <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>e</mi><mi>v</mi><mi>e</mi><mi>n</mi><mi>t</mi><mo separator="true">,</mo><mi>C</mi><mi>o</mi><mi>n</mi><mi>t</mi><mi>e</mi><mi>x</mi><mi>t</mi></mrow><annotation encoding="application/x-tex">event, Context </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8778em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mord mathnormal">e</span><span class="mord mathnormal">n</span><span class="mord mathnormal">t</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord mathnormal" style="margin-right:0.07153em;">C</span><span class="mord mathnormal">o</span><span class="mord mathnormal">n</span><span class="mord mathnormal">t</span><span class="mord mathnormal">e</span><span class="mord mathnormal">x</span><span class="mord mathnormal">t</span></span></span></span>context): void  
    {  
        $this->logger->info("Processing SQS records");  
        <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>r</mi><mi>e</mi><mi>c</mi><mi>o</mi><mi>r</mi><mi>d</mi><mi>s</mi><mo>=</mo></mrow><annotation encoding="application/x-tex">records = </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">recor</span><span class="mord mathnormal">d</span><span class="mord mathnormal">s</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span></span></span></span>event->getRecords();  
        foreach ($records as $record) {  
            try {  
                // Assuming the SQS message is in JSON format  
                <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi><mi>e</mi><mi>s</mi><mi>s</mi><mi>a</mi><mi>g</mi><mi>e</mi><mo>=</mo><mi>j</mi><mi>s</mi><mi>o</mi><msub><mi>n</mi><mi>d</mi></msub><mi>e</mi><mi>c</mi><mi>o</mi><mi>d</mi><mi>e</mi><mo stretchy="false">(</mo></mrow><annotation encoding="application/x-tex">message = json_decode(</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">m</span><span class="mord mathnormal">ess</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">e</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.05724em;">j</span><span class="mord mathnormal">so</span><span class="mord"><span class="mord mathnormal">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">d</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord mathnormal">eco</span><span class="mord mathnormal">d</span><span class="mord mathnormal">e</span><span class="mopen">(</span></span></span></span>record->getBody(), true);  
                <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>t</mi><mi>h</mi><mi>i</mi><mi>s</mi><mo>−</mo><mo>&gt;</mo><mi>l</mi><mi>o</mi><mi>g</mi><mi>g</mi><mi>e</mi><mi>r</mi><mo>−</mo><mo>&gt;</mo><mi>i</mi><mi>n</mi><mi>f</mi><mi>o</mi><mo stretchy="false">(</mo><mi>j</mi><mi>s</mi><mi>o</mi><msub><mi>n</mi><mi>e</mi></msub><mi>n</mi><mi>c</mi><mi>o</mi><mi>d</mi><mi>e</mi><mo stretchy="false">(</mo></mrow><annotation encoding="application/x-tex">this-&gt;logger-&gt;info(json_encode(</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7778em;vertical-align:-0.0833em;"></span><span class="mord mathnormal">t</span><span class="mord mathnormal">hi</span><span class="mord mathnormal">s</span><span class="mord">−</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">&gt;</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">o</span><span class="mord mathnormal" style="margin-right:0.03588em;">gg</span><span class="mord mathnormal" style="margin-right:0.02778em;">er</span><span class="mord">−</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">&gt;</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">in</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord mathnormal">o</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.05724em;">j</span><span class="mord mathnormal">so</span><span class="mord"><span class="mord mathnormal">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.1514em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">e</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord mathnormal">n</span><span class="mord mathnormal">co</span><span class="mord mathnormal">d</span><span class="mord mathnormal">e</span><span class="mopen">(</span></span></span></span>message));  
                // TODO: Implement your custom processing logic here  
            } catch (Exception $e) {  
                <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>t</mi><mi>h</mi><mi>i</mi><mi>s</mi><mo>−</mo><mo>&gt;</mo><mi>l</mi><mi>o</mi><mi>g</mi><mi>g</mi><mi>e</mi><mi>r</mi><mo>−</mo><mo>&gt;</mo><mi>e</mi><mi>r</mi><mi>r</mi><mi>o</mi><mi>r</mi><mo stretchy="false">(</mo></mrow><annotation encoding="application/x-tex">this-&gt;logger-&gt;error(</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7778em;vertical-align:-0.0833em;"></span><span class="mord mathnormal">t</span><span class="mord mathnormal">hi</span><span class="mord mathnormal">s</span><span class="mord">−</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">&gt;</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">o</span><span class="mord mathnormal" style="margin-right:0.03588em;">gg</span><span class="mord mathnormal" style="margin-right:0.02778em;">er</span><span class="mord">−</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">&gt;</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">error</span><span class="mopen">(</span></span></span></span>e->getMessage());  
                // failed processing the record  
                <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>t</mi><mi>h</mi><mi>i</mi><mi>s</mi><mo>−</mo><mo>&gt;</mo><mi>m</mi><mi>a</mi><mi>r</mi><mi>k</mi><mi>A</mi><mi>s</mi><mi>F</mi><mi>a</mi><mi>i</mi><mi>l</mi><mi>e</mi><mi>d</mi><mo stretchy="false">(</mo></mrow><annotation encoding="application/x-tex">this-&gt;markAsFailed(</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7778em;vertical-align:-0.0833em;"></span><span class="mord mathnormal">t</span><span class="mord mathnormal">hi</span><span class="mord mathnormal">s</span><span class="mord">−</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">&gt;</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">ma</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mord mathnormal">A</span><span class="mord mathnormal">s</span><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="mord mathnormal">ai</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">e</span><span class="mord mathnormal">d</span><span class="mopen">(</span></span></span></span>record);  
            }  
        }  
        <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>t</mi><mi>o</mi><mi>t</mi><mi>a</mi><mi>l</mi><mi>R</mi><mi>e</mi><mi>c</mi><mi>o</mi><mi>r</mi><mi>d</mi><mi>s</mi><mo>=</mo><mi>c</mi><mi>o</mi><mi>u</mi><mi>n</mi><mi>t</mi><mo stretchy="false">(</mo></mrow><annotation encoding="application/x-tex">totalRecords = count(</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">t</span><span class="mord mathnormal">o</span><span class="mord mathnormal">t</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.00773em;">lR</span><span class="mord mathnormal" style="margin-right:0.02778em;">ecor</span><span class="mord mathnormal">d</span><span class="mord mathnormal">s</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">co</span><span class="mord mathnormal">u</span><span class="mord mathnormal">n</span><span class="mord mathnormal">t</span><span class="mopen">(</span></span></span></span>records);  
        <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>t</mi><mi>h</mi><mi>i</mi><mi>s</mi><mo>−</mo><mo>&gt;</mo><mi>l</mi><mi>o</mi><mi>g</mi><mi>g</mi><mi>e</mi><mi>r</mi><mo>−</mo><mo>&gt;</mo><mi>i</mi><mi>n</mi><mi>f</mi><mi>o</mi><mo stretchy="false">(</mo><mi mathvariant="normal">&quot;</mi><mi>S</mi><mi>u</mi><mi>c</mi><mi>c</mi><mi>e</mi><mi>s</mi><mi>s</mi><mi>f</mi><mi>u</mi><mi>l</mi><mi>l</mi><mi>y</mi><mi>p</mi><mi>r</mi><mi>o</mi><mi>c</mi><mi>e</mi><mi>s</mi><mi>s</mi><mi>e</mi><mi>d</mi></mrow><annotation encoding="application/x-tex">this-&gt;logger-&gt;info(&quot;Successfully processed </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7778em;vertical-align:-0.0833em;"></span><span class="mord mathnormal">t</span><span class="mord mathnormal">hi</span><span class="mord mathnormal">s</span><span class="mord">−</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">&gt;</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">o</span><span class="mord mathnormal" style="margin-right:0.03588em;">gg</span><span class="mord mathnormal" style="margin-right:0.02778em;">er</span><span class="mord">−</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">&gt;</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">in</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord mathnormal">o</span><span class="mopen">(</span><span class="mord">&quot;</span><span class="mord mathnormal" style="margin-right:0.05764em;">S</span><span class="mord mathnormal">u</span><span class="mord mathnormal">ccess</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord mathnormal">u</span><span class="mord mathnormal" style="margin-right:0.01968em;">ll</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mord mathnormal">p</span><span class="mord mathnormal">rocesse</span><span class="mord mathnormal">d</span></span></span></span>totalRecords SQS records");  
    }  
}  
$logger = new StderrLogger();  
return new Handler($logger);  

Python
SDK for Python (Boto3)

Note

There's more on GitHub. Find the complete example and learn how to set up and run in theServerless examples repository.
Reporting SQS batch item failures with Lambda using Python.

# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.  
# SPDX-License-Identifier: Apache-2.0  
def lambda_handler(event, context):  
    if event:  
        batch_item_failures = []  
        sqs_batch_response = {}  
       
        for record in event["Records"]:  
            try:  
                # process message  
            except Exception as e:  
                batch_item_failures.append({"itemIdentifier": record['messageId']})  
          
        sqs_batch_response["batchItemFailures"] = batch_item_failures  
        return sqs_batch_response  

Ruby
SDK for Ruby

Note

There's more on GitHub. Find the complete example and learn how to set up and run in theServerless examples repository.
Reporting SQS batch item failures with Lambda using Ruby.

# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.  
# SPDX-License-Identifier: Apache-2.0  
require 'json'  
def lambda_handler(event:, context:)  
  if event  
    batch_item_failures = []  
    sqs_batch_response = {}  
    event["Records"].each do |record|  
      begin  
        # process message  
      rescue StandardError => e  
        batch_item_failures << {"itemIdentifier" => record['messageId']}  
      end  
    end  
    sqs_batch_response["batchItemFailures"] = batch_item_failures  
    return sqs_batch_response  
  end  
end  

Rust
SDK for Rust

Note

There's more on GitHub. Find the complete example and learn how to set up and run in theServerless examples repository.
Reporting SQS batch item failures with Lambda using Rust.

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.  
// SPDX-License-Identifier: Apache-2.0  
use aws_lambda_events::{  
    event::sqs::{SqsBatchResponse, SqsEvent},  
    sqs::{BatchItemFailure, SqsMessage},  
};  
use lambda_runtime::{run, service_fn, Error, LambdaEvent};  
async fn process_record(_: &SqsMessage) -> Result<(), Error> {  
    Err(Error::from("Error processing message"))  
}  
async fn function_handler(event: LambdaEvent<SqsEvent>) -> Result<SqsBatchResponse, Error> {  
    let mut batch_item_failures = Vec::new();  
    for record in event.payload.records {  
        match process_record(&record).await {  
            Ok(_) => (),  
            Err(_) => batch_item_failures.push(BatchItemFailure {  
                item_identifier: record.message_id.unwrap(),  
            }),  
        }  
    }  
    Ok(SqsBatchResponse {  
        batch_item_failures,  
    })  
}  
#[tokio::main]  
async fn main() -> Result<(), Error> {  
    run(service_fn(function_handler)).await  
}  

If the failed events do not return to the queue, see How do I troubleshoot Lambda function SQS ReportBatchItemFailures? in the AWS Knowledge Center.

Success and failure conditions

Lambda treats a batch as a complete success if your function returns any of the following:

Lambda treats a batch as a complete failure if your function returns any of the following:

CloudWatch metrics

To determine whether your function is correctly reporting batch item failures, you can monitor theNumberOfMessagesDeleted and ApproximateAgeOfOldestMessage Amazon SQS metrics in Amazon CloudWatch.