Is there any way to catch AWS lambda timed out
error in code-level so that I can have a chance to handle for the error before exiting the lambda
function?
You can now set the timeout value for a function to any value up to 15 minutes. When the specified timeout is reached, Amazon Lambda terminates execution of your Lambda function.
To troubleshoot Lambda code errors You can use CloudWatch to view all logs generated by your function's code and identify potential issues. For more information, see Accessing Amazon CloudWatch Logs for AWS Lambda.
Finding the root cause of the timeout. There are many reasons why a function might time out, but the most likely is that it was waiting on an IO operation to complete.
While the lambda environment doesn't fire a "timing out" event, you can do this yourself fairly trivially.
Each language has a function exposed by the context
object to get the remaining time in milliseconds.
You can use that, in tandem with the timer functionality of whatever language you're using to ensure you get notified before timeout.
For example (node):
function handler(event, context, callback) { const timer = setTimeout(() => { console.log("oh no i'm going to timeout in 3 seconds!"); // &c. }, context.getRemainingTimeInMillis() - 3 * 1000); try { // rest of code... } finally { clearTimeout(timer); } callback(null, result); }
Use the built-in Promise.race()
function instead:
module.exports.myFunction = async (event) => { // your real task const task = new Promise((resolve) => { setTimeout(() => resolve({ statusCode: 200, message: 'Task finished.' }), 1000); }) // add a new "task": timeout const timeout = new Promise((resolve) => { setTimeout(() => resolve({ statusCode: 504, message: 'Sorry, your task timed out!' }), 200); }) // start them synchronously const res = await Promise.race([task, timeout]); return res; };
I would like to share my solution here:
Let's say I have a Lambda handler function and it's timeout limit I set was 15 mins. Inside this function, I have an async function named work()
which may takes longer that 15 mins.
To catch the timeout error from Lambda, my way is:
I create a new async function named timeout()
, and this function simply return after 14.9 mins. And I let work()
and timeout()
functions start at the same time, if work()
can finish in 14.9 mins, then work()
returns earlier that timeout()
, otherwise, timeout()
returns earlier.
You can see it easier with this diagram:
And this is just what race()
operator does from rxjs
.
Here is the code that implement this idea by using rxjs
:
module.exports.myFunction = async (event) => { function task() { return new Promise((resolve, reject) => { setTimeout(() => { resolve('finished!'); }, 15 * 60 * 1000); }); } function timeout() { return new Promise((resolve, reject) => { setTimeout(() => { resolve('timeout!'); }, 14.9 * 60 * 1000); }); } const res = await new Promise((resolve, reject) => { race(from(task()), from(timeout())) .subscribe(msg => { resolve(msg); }) }); return { res }; };
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With