Search code examples
javascriptnode.jsamazon-s3aws-lambdaaws-sdk-js

AWS SDK JS httpOptions timeout intermittently not working


I have deployed an AWS Lambda function for reading and serving S3 files. AWS SDK JS is initialized with these options

awsS3CustomConfig = {
        maxRetries: parseInt(1),
        httpOptions: {
          timeout: parseInt(1000),
        },
      }

While sometimes the code is working fine an I am getting this timeout exception in Lambda logs

{"response":{"statusCode":500,"headers":{},"body":"{\"status\":500,\"timestamp\":\"2023-06-12T23:52:40.865Z\",\"description\":\"Connection timed out after 1000ms\",\"message\":\"generalError\",\"subErrors\":[\"TimeoutError\"]}"}}

Mostly I am getting this log from SDK

{"message":"[AWS s3 200 130.776s 1 retries] getObject({\\n  Bucket: 'aue1p1z1s3bd*****',\\n  Key: 'bright/listing/802315843012.json',\\n  VersionId: undefined\\n})"}`

There are two problems here

  1. Why SDK didn't timeout even after more than 130 seconds (timeout is just 1 sec)?
  2. Why SDK logging 200 status instead of raising timeout error?

Solution

  • I was facing the same issue after implementing httpOptions.timeout with aws-sdk, implementing abort method with setTimeout method of javascript fixed this issue for me.

    const s3 = new AWS.S3({ maxRetries: 1 })
    
    async function putObjectInS3(Bucket: string, Key: string, Body?: string, Tagging?: string): Promise<AWS.S3.Types.PutObjectOutput> {
      const params: AWS.S3.Types.PutObjectRequest = { Bucket, Key, Body, Tagging }
    
      const putObjectReq = s3.putObject(params)
      setTimeout(putObjectReq.abort.bind(putObjectReq), 3000) // 3 seconds timeout
    
      return putObjectReq.promise()
    }

    Please note that even though abort implementation works much better as compared to httpOptions.timeout, it also has chances to fail. I have noticed in my system it works 99.999% of times which is satisfactory for me.