UNPKG

serverless-offline

Version:

Emulate AWS λ and API Gateway locally when developing your Serverless project

99 lines (73 loc) 3.36 kB
'use strict'; const ac = require('./state/actionCreators'); const createApigContext = require('./createApigContext'); // const createLambdaContext = require('./createLambdaContext'); const createLambdaCallback = require('./createLambdaCallback'); const renderVelocityTemplateObject = require('./renderVelocityTemplateObject'); const reply500 = require('./reply500'); const log = require('./utils/log'); const logDebug = require('./utils/logDebug'); module.exports = function createRouteHandler(fun, endpoint, funOptions, noTimeout) { const funName = fun.name; const funTimeout = (fun.timeout || 6) * 1000; const method = endpoint.method.toUpperCase(); const loadAndCallHandler = require(`runtimes/${fun.runtime}/loadAndCallHandler`); let isFirstCall = true; return (request, reply) => { // const state = store.getState(); console.log(); log(`${method} ${request.path} (λ: ${funName})`); if (isFirstCall) { log('The first request might take a few extra seconds'); isFirstCall = false; } // Holds the response to do async op const requestId = request.id; const response = reply.response().hold(); const contentType = request.mime || 'application/json'; const requestTemplate = endpoint.requestTemplates[contentType]; logDebug('requestId:', requestId); logDebug('contentType:', contentType); logDebug('requestTemplate:', requestTemplate); if (request.payload) logDebug('payload:', request.payload); /* BABEL CONFIGURATION */ // TODO, rethink it // _registerBabel(funRuntime === 'babel', funBabelOptions); /* REQUEST TEMPLATE PROCESSING (event population) */ let lambdaEvent = {}; if (requestTemplate) { try { logDebug('_____ REQUEST TEMPLATE PROCESSING _____'); // Velocity templating language parsing lambdaEvent = renderVelocityTemplateObject(requestTemplate, createApigContext(request, request.payload || {})); logDebug('end__ REQUEST TEMPLATE PROCESSING __end'); } catch (err) { return reply500(response, `Error while parsing template '${contentType}' for '${funName}'`, err, requestId); } } lambdaEvent.isOffline = true; logDebug('event:', lambdaEvent); // The Lambda callback is responsible for calling the HTTP response const lambdaCallback = createLambdaCallback(); // We cannot use Hapijs's timeout feature because the logic above can take a significant time, so we implement it ourselves let timeout; if (!noTimeout) timeout = setTimeout(() => { // if (this.currentRequestId !== requestId) return; //TODO: test that shit log(`Replying timeout after ${funTimeout}ms`); ac.markRequestDone({ requestId }); response.statusCode = 503; response.source = `[Serverless-Offline] Your λ handler '${funName}' timed out after ${funTimeout}ms.`; response.send(); }, funTimeout); ac.createRequest({ requestId, timeout }); // Finally we call the handler logDebug('_____ CALLING HANDLER _____'); try { loadAndCallHandler(funName, funOptions.handlerPath, funOptions.handlerParts, lambdaEvent, lambdaCallback); } catch(err) { return reply500(err, requestId, response); } }; };