Skip to content

Commit 826da2c

Browse files
authored
Merge pull request #113 from jvandervelden/jvandervelden/handle-multi-next
Handle multiple calls to next()
2 parents 152aa10 + 14ec0bc commit 826da2c

4 files changed

Lines changed: 68 additions & 18 deletions

File tree

lib/handler.js

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,38 @@
11
'use strict';
22

3-
async function dispatch(middleware, state, i = 0) {
3+
async function dispatch(middleware, event, context, i = 0) {
44
const fn = middleware[i] || Function.prototype;
5-
const next = async (err, context, event) => {
5+
let prevResult;
6+
const next = async (err, nxtContext, nxtEvent) => {
67
if (err) {
78
throw err;
89
}
910

10-
if (context !== undefined && context !== null) {
11-
state.context = context;
12-
}
11+
const result = await dispatch(middleware, nxtEvent || event, nxtContext || context, i + 1);
1312

14-
if (event !== undefined && event !== null) {
15-
state.event = event;
13+
// Save result if one was passed
14+
if (result !== undefined) {
15+
prevResult = result;
1616
}
1717

18-
await dispatch(middleware, state, i + 1);
19-
20-
return state.result;
18+
return result;
2119
};
2220

23-
const result = await fn(state.event, state.context, next);
21+
const result = await fn(event, context, next);
2422

25-
if (result !== undefined) {
26-
state.result = result;
23+
// Use result from previous middleware if this one didn't pass back a result
24+
if (result === undefined) {
25+
return prevResult;
2726
}
2827

29-
return state;
28+
return result;
3029
}
3130

3231
module.exports = function () {
3332
const middleware = [];
3433

3534
const handler = async (event, context) => {
36-
const { result } = await dispatch(middleware, { event, context });
37-
return result;
35+
return dispatch(middleware, event, context);
3836
};
3937

4038
handler.use = mw => {

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@alpha-lambda/handler",
3-
"version": "1.2.1",
3+
"version": "1.3.0",
44
"description": "Middleware pipeline for AWS Lambda handlers",
55
"repository": {
66
"type": "git",

test/lambda-handler-tests.js

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,34 @@ describe('handler', function() {
346346
});
347347
});
348348

349+
it('next() called with no more middleware, return undefined', function() {
350+
const result = { foo: 'foo' };
351+
352+
const fixture = lambdaHandler()
353+
.use((event, context, next) => next(null, context, result));
354+
355+
return fixture(testEvent, testContext)
356+
.then(nextResult => {
357+
expect(nextResult).to.be.undefined;
358+
});
359+
});
360+
361+
it('next() called with no more middleware, return last returned result', function() {
362+
const result = { foo: 'foo' };
363+
364+
const fixture = lambdaHandler()
365+
.use(async (event, context, next) => {
366+
await next();
367+
return result;
368+
})
369+
.use((event, context, next) => next());
370+
371+
return fixture(testEvent, testContext)
372+
.then(nextResult => {
373+
expect(nextResult).to.equal(result);
374+
});
375+
});
376+
349377
it('next() call is resolved with result value when it is overridden after calling chained next', function() {
350378
const result1 = { foo: 'foo' };
351379
const result2 = { bar: 'bar' };
@@ -367,6 +395,30 @@ describe('handler', function() {
367395
});
368396
});
369397

398+
it('next() can be called multiple times and result is handled', function() {
399+
const multiEvent = ['f', 'b'];
400+
const resultMap = {
401+
f: { foo: 'foo' },
402+
b: { bar: 'bar' }
403+
};
404+
405+
const fixture = lambdaHandler()
406+
.use(async (events, context, next) => {
407+
return Promise.all(events.map(event => next(null, context, event)));
408+
})
409+
.use(async (event, context, next) => {
410+
await next();
411+
})
412+
.use(async event => {
413+
return resultMap[event];
414+
});
415+
416+
return fixture(multiEvent, testContext)
417+
.then(result => {
418+
expect(result).to.deep.equal([resultMap.f, resultMap.b]);
419+
});
420+
});
421+
370422
it('has expected execution order', function() {
371423
const order = [];
372424
const fixture = lambdaHandler()

0 commit comments

Comments
 (0)