Intercepting the AWS Lambda Timeout
When a Lambda function times out, it gives no warning — boom, your function just stops executing.
One can generally estimate how long a Lambda function will run, and add some cushion, but stuff happens and we should Promise to handle the unexpected as gracefully as possible !!
Approach
Create 2 Promises (P1/P2) and wait (race) until 1 of them finishes.
P1: Set a timeout to something less than the Lambda function timeout
P2: Run your business logic
The trick is then using Promise.race to capture when ONE of the promises finishes. In theory, the timeout should almost never happen first. Following is a super-skeletal structure of how you could handle.
exports.handler = async(event, context) => { const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
reject('Timer Expired');
}, context.getRemainingTimeInMillis() - 5000);
// 5 seconds before actual expiration
}); const p2 = bizLogic(); let resultsObject; await Promise.race([p1, p2])
.then(value => resultsObject = value)
.catch(reason => resultsObject = null); if ( resultsObject ) {
// Happy Place
}
else {
// #sad / timed out
} return 'done';
}const bizLogic = async() => { // Your business logic here return someObject;}
Promises are a weird and wonderful construct, and you’re probably somewhat familiar with them. As such, there are many ways to implement the above, but conceptually this should help to, at least intercept & know about, the dreaded timeout scenario.
You will be known for your graceful terminations!