0

Im invoking a lambda function to compress images uploaded to a bucket and then write the compressed image to another bucket

The code executes fine it fetches the image but for some reason it fails to write the compressed image to the new bucket

Here is my code:


//Import compress module
const imagemin = require('imagemin');
const imageminMozjpeg = require('imagemin-mozjpeg');
const sharp = require('sharp');

const AWS = require('aws-sdk')

const s3 = new AWS.S3()
exports.handler = async (event) =>{
    // TODO implement
    
    const srcBucket = event.Records[0].s3.bucket.name;
    
    const srcKey    = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, " "));
    const dstBucket = "safarni";
    const dstKey    =  srcKey;
    
    console.log(srcKey, dstBucket, dstKey)
     // Download the image from the S3 source bucket. 
    try {
        const params = {
            Bucket: srcBucket,
            Key: srcKey
        };
        var origimage = await s3.getObject(params).promise();

    } catch (error) {

        console.log('here');
        return;
    }  
    
    const jpgBuffer = await sharp(origimage.Body).jpeg().toBuffer()
    
    //Compressing the photo
    const compressedjpgBuffer = await imagemin.buffer(jpgBuffer, {
            plugins: [imageminMozjpeg({ quality: 85 })]
    })
       
    console.log(compressedjpgBuffer)    
    // Upload the thumbnail image to the destination bucket
    try {
        const destparams = {
            Bucket: dstBucket,
            Key: dstKey,
            Body: compressedjpgBuffer,    
        };

        const putResult = await s3.putObject(destparams).promise(); 
        
    } catch (error) {
        console.log(error);
        return;
    } 
        
    console.log('Successfully resized ' + srcBucket + '/' + srcKey +
        ' and uploaded to ' + dstBucket + '/' + dstKey); 
    const response = {
        statusCode: 200,
        body: JSON.stringify('Hello from Lambda!'),
    };
    return response;
};

This is an image of the log enter image description here

1
  • Did your function timeout, does increasing timeout allow it to complete? Commented Jul 18, 2020 at 9:45

2 Answers 2

1

You function is timing out from this log you provided. Perform one (or both the below options)

  • Increase the timeout past the 3 seconds (this is the default value). It can be increased upto 15 minutes, you should aim to set the timeout to match the expected time it should take to perform the action.
  • Increase (Memory/CPU allocation).

Either of these can be changed in the console by clicking Edit above the basic settings section, then modifying to the appropriate values as shown below.

enter image description here

Once the timeout is exceeded the function will fail to continue.

Sign up to request clarification or add additional context in comments.

Comments

1

Try to change your code like this:

const imagemin = require('imagemin');
const imageminMozjpeg = require('imagemin-mozjpeg');
const sharp = require('sharp');
const AWS = require("aws-sdk");

const s3 = new AWS.S3();

exports.handler = async (event) => {
  const s3MetaData = event.Records[0].s3;
  const srcBucket = s3MetaData.bucket.name;
  const srcKey = s3MetaData.object.key;

  const dstBucket = "safarni";
  const dstKey = `compressed_${srcKey}`;

  try {
    const srcParams = {
      Bucket: srcBucket,
      Key: srcKey
    };

    const origImage = await s3.getObject(srcParams).promise();

    const jpgBuffer = await sharp(origImage.Body).jpeg().toBuffer();

    const compressedJPGBuffer = await imagemin.buffer(jpgBuffer, 
      { plugins: [imageminMozjpeg({ quality: 85 })] });

    const destParams = {
      Bucket: dstBucket,
      Key: dstKey,
      Body: compressedJPGBuffer
    }

    const newImage = await s3.putObject(destParams).promise();

    return {
      statusCode: 200,
      body: "Lambda successfully executed"
    }

  } catch (err) {
    console.error(`The following error occurred: ${err.message}`);
    throw err;
  }
}

Make sure you have the following policy applied:

- Action:
  - s3:putObject
  - s3:getObject
Effect: Allow
Resource:
  Fn::Join:
    - ""
    - - "arn:aws:s3:::"
      - Ref: YourBucket
        - /*

And also increase the timeout because apparently it is timing out after 3 seconds.

1 Comment

I increased the timeout and it solved the issue thank you

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.