AWS Lambda function continues a bit after context.fail

I have a simple AWS Lambda function that does some validation on images stored in an S3 bucket. I use async.waterfall to upload the image and process it, but before I even enter the first function of the waterfall, I do some basic checking of the event data that I get from my S3 PutObject trigger, in particular the size information ( event.Records[0].s3.object.size ). If the event refers to an image that is larger than my MAX_SIZE, I use context.fail(new Error("Validation error: the file is too big.")) To complete the execution.

Everything works fine, but in my logs, I notice that after registering the error, the function continues to work a little until its exit. For example, the first function in my call async.waterfall is called (i.e. the message from this function is displayed in the log). I even tried to add context.done(errorMessage) right after the context.fail file, and it starts (i.e. the message I send is logged) along with a few lines of code.

Is this the expected behavior? I could not find mention of this in the docs. Does the function take a little time to exit or do I misunderstand the synchronous nature of the code in the handler function, which BEFORE async.waterfall ?

The following is part of my code. All console.log messages that appear after context.fail are printed in a log, which I would not expect.

 exports.handler = function(event, context) { console.log('Received event:', JSON.stringify(event, null, 2)); if (event.Records[0].s3.object.size > MAX_FILE_SIZE) { var error = new Error("Validation error: the file is too big.") context.fail(error); } console.log('Event validation complete.') var bucket = event.Records[0].s3.bucket.name; var key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' ')); var fileName = key.split("/")[1]; var params = { Bucket: bucket, Key: key }; console.log('Starting processing of the following file: ' + JSON.stringify(params, null, 2)); async.waterfall([ function download(callback) { // Download the image from S3 into a buffer. console.log("Downloading the image from S3..."); s3.getObject(params, function(err, data) { if (err) { callback(err); } else { callback(null, data); } }); }, ... ], ...) } 
+5
source share
2 answers

This seems to be the expected behavior, even if it is poorly documented. the contextual documentation says that fail() indicates a failure, but does not promise to stop further execution.

context.fail ()

Indicates that the Lambda function is executing, and all callbacks fail, resulting in a handler exception.

The good news for your code is that from return from a function after context.fail() executed, return should be easy enough to avoid further processing.

+2
source

I believe the aws lambda structure has changed a bit since this question has been asked (and James answer).

Now the handler additionally has a third argument , 'callback', which can be called to stop script execution. Depending on how you call it, it successfully terminates the process or with an error. See these documents for details.

Also, check the context property, callbackWaitsForEmptyEventLoop . It defaults to true, but you need to set it to false so that after calling the callback, the node process does not wait for the execution loop to be cleared, i.e. Your asynchronous calls have been dropped.

+9
source

Source: https://habr.com/ru/post/1244073/


All Articles