Skip to content

Instantly share code, notes, and snippets.

@anthonyroach
Forked from IronSavior/example-error.js
Created May 16, 2018 19:52
Show Gist options
  • Save anthonyroach/6e0daa204496b9eecfa583b1848d0468 to your computer and use it in GitHub Desktop.
Save anthonyroach/6e0daa204496b9eecfa583b1848d0468 to your computer and use it in GitHub Desktop.
Require AWS Lambda handler to invoke callback before exit (prevent Node exit until handler invokes callback)
const lambda_handler = require('lambda-handler');
exports.handler = lambda_handler(( event, ctx, done ) => {
// This will log a handled error to CloudWatch and return the error to AWS Lambda
throw 'BOOM!';
});
const lambda_handler = require('lambda-handler');
exports.handler = lambda_handler(( event, ctx, done ) => {
// This invocation will return "Complete!" to AWS Lambda as the function's output.
done(null, 'Complete!');
});
const lambda_handler = require('lambda-handler');
exports.handler = lambda_handler(( event, ctx, done ) => {
// This handler doesn't change the event loop. Normally Lambda would immediately exit
// with null output, but wrapping it in lambda_handler() prevents that. This handler will
// eventually time out and be killed by AWS Lambda.
});
const log = console;
// Wrap a handler function
module.exports = handler => (...args) => invoke_handler(handler, ...args);
module.exports.invoke_handler = invoke_handler;
// Invoke AWS Lambda handler and ensure that Node will not exit until the handler explicitly invokes its callback.
// This can help work around issues where your Lambda handlers mysteriously seem to exit early and with no output.
// Input, output, and errors are automatically logged for CloudWatch before returning to AWS Lambda.
// @param handler {Function} Handler function
// @param event {Object} AWS Lambda input event (forwarded to handler)
// @param context {Object} AWS Lambda context (forwarded to handler)
// @param done {Function} AWS Lambda completion callback
// @returns value returned by handler
function invoke_handler( handler, event, context, done ){
log.info('Event:', event);
log.info('Context:', context);
let finished = false;
prevent_exit_until_finished();
try{
return handler(event, context, finish);
}
catch(e){
finish(e);
}
// Ensures the Node event loop never ends until handler explicitly signals completion via callback
// @param interval_ms {Integer} Timeout interval in milliseconds between checks
// @returns {void}
function prevent_exit_until_finished( interval_ms = 25 ){
if( finished ) return;
setTimeout(prevent_exit_until_finished, interval_ms);
}
// Invoked by handler to signal completion
// @param err {Object} Handler error (null when successfully completed)
// @param output {Object} Output returned to AWS Lambda
// @returns {void}
function finish( err, output ){
if( finished ) log.error('Handler signaled completion too many times!');
if( err ) log.trace(finished ? 'Lambda Error (redundant, ignored):' : 'Lambda Error:', err);
else log.info(finished ? 'Lambda Output (redundant, ignored):' : 'Lambda Output:', output);
finished = true;
done(...arguments);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment