Dasith U Edirisinghe
Dasith U Edirisinghe

Reputation: 51

Lambda doesn't reattempt processing the SQS message even after an error is returned from the handler

I am trying to invoke the lambda function using standard SQS. I have handled errors using a try-catch block and whenever an error is caught, it will be returned. Otherwise, a response message will be returned with 200 OK.

I want to reprocess the messages which returned errors. But lambda won't reprocess those messages. Even the Retention time period(5 min) > Visibility time out(1 min) Why does this happen?

const { spawnSync, execSync } = require('child_process');
const fs = require('fs');
const { S3Client, GetObjectCommand, PutObjectCommand } = require("@aws-sdk/client-s3");
const { DynamoDBClient, UpdateItemCommand } = require("@aws-sdk/client-dynamodb");
const { marshall } = require('@aws-sdk/util-dynamodb');

exports.lambdaHandler = async (event) => {

  try {

    const body = JSON.parse(event["Records"][0]['body']);

    try {

      // Code base 1
      // All the above imported dependencies will be used here

      const response = {
        statusCode: 200,
        body: JSON.stringify({ message: "Function Executed" })
      };
    
      console.log('Response: ',response);
      return response;

    }
    catch (err) {
      console.log("[ERROR]: ", err);
      console.log('body is: ', body);
      console.log("err returning");
      return err;
    }
  }

  catch (error) {
    console.log("[ERROR]: ", error);
    console.log("error returning");
    return error;
  }

  

};


// Below functions are used in code base 1
// No try catch block or error hadling in below code bases

async function downloadFile() {
  
    //code base 2
};


async function uploadFile() {
 // code base 3
};


async function updateUsdz() {
  // code base 4
}

Upvotes: 1

Views: 1893

Answers (1)

stijndepestel
stijndepestel

Reputation: 3554

You are, as you say, literally returning the error. However, for lambda in this scenario, you're simply returning an object. It does not matter whether or not the object is an error object or any other object. According to the system, your lambda will have been successfully executed, the SQS service will receive a success response from AWS Lambda and the message will be dropped from the queue as it is handled.

If you want to use the retry functionality that SQS provides, you must ensure that you're lambda fails. In this case, this means actually throwing the error again after you've executed the code you want to execute on failure (e.g., logging the error). If you throw the error, the handler function will fail (instead of simply returning an error object) and the message will not be deleted from the SQS queue but will be retried.

For example:

exports.lambdaHandler = async (event) => {
  try {
    // Do something
  } catch (error) {
    console.log("[ERROR]: ", error);
    throw error;
  }
};

As a side note, if you're using a solution like this, ensure you are attaching a dead-letter queue to your SQS queue in order to catch messages that can never be handled by the lambda. If you do not have such a queue to catch those messages, these will keep being retried which effectively creates an infinite loop which could cost quite a lot of money.

Upvotes: 6

Related Questions