即使从处理程序返回错误后,Lambda 也不会重新尝试处理 SQS 消息

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

我正在尝试使用标准 SQS 调用 lambda 函数。我已经使用 try-catch 块处理了错误,只要捕获到错误,就会返回错误。否则,将返回一条带有 200 OK 的响应消息。

我想重新处理返回错误的消息。但是 lambda 不会重新处理这些消息。 甚至 Retention time period(5 min) > Visibility time out(1 min) 为什么会这样?

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
}

正如您所说,您实际上是在返回错误。但是,对于这种情况下的 lambda,您只是返回一个对象。对象是错误对象还是任何其他对象都无关紧要。根据系统,您的 lambda 将已成功执行,SQS 服务将收到来自 AWS Lambda 的成功响应,并且消息将在处理时从队列中删除。

如果您想使用SQS 提供的重试功能,您必须确保您的lambda 失败。在这种情况下,这意味着在您执行了您想要在失败时执行的代码(例如,记录错误)之后再次抛出错误。如果抛出错误,处理函数将失败(而不是简单地返回一个错误对象)并且消息不会从 SQS 队列中删除但会重试。

例如:

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

附带说明一下,如果您使用的是这样的解决方案,请确保将 dead-letter queue 附加到您的 SQS 队列,以捕获 lambda 永远无法处理的消息。如果您没有这样的队列来捕获这些消息,这些消息将不断重试,这实际上会创建一个无限循环,这可能会花费很多钱。