Skip to content

Commit d5f3f13

Browse files
authoredJun 22, 2023
feat(logger): clear state when other middlewares return early (#1544)
1 parent 6f96711 commit d5f3f13

File tree

2 files changed

+77
-2
lines changed

2 files changed

+77
-2
lines changed
 

‎packages/logger/src/middleware/middy.ts

+18-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Logger } from '../Logger';
22
import { HandlerOptions, LogAttributes } from '../types';
3+
import { LOGGER_KEY } from '@aws-lambda-powertools/commons/lib/middleware';
34
import type {
45
MiddlewareLikeObj,
56
MiddyLikeRequest,
@@ -35,15 +36,30 @@ const injectLambdaContext = (
3536
): MiddlewareLikeObj => {
3637
const loggers = target instanceof Array ? target : [target];
3738
const persistentAttributes: LogAttributes[] = [];
39+
const isClearState = options && options.clearState === true;
40+
41+
/**
42+
* Set the cleanup function to be called in case other middlewares return early.
43+
*
44+
* @param request - The request object
45+
*/
46+
const setCleanupFunction = (request: MiddyLikeRequest): void => {
47+
request.internal = {
48+
...request.internal,
49+
[LOGGER_KEY]: injectLambdaContextAfterOrOnError,
50+
};
51+
};
3852

3953
const injectLambdaContextBefore = async (
4054
request: MiddyLikeRequest
4155
): Promise<void> => {
4256
loggers.forEach((logger: Logger, index: number) => {
43-
if (options && options.clearState === true) {
57+
if (isClearState) {
4458
persistentAttributes[index] = {
4559
...logger.getPersistentLogAttributes(),
4660
};
61+
62+
setCleanupFunction(request);
4763
}
4864
Logger.injectLambdaContextBefore(
4965
logger,
@@ -55,7 +71,7 @@ const injectLambdaContext = (
5571
};
5672

5773
const injectLambdaContextAfterOrOnError = async (): Promise<void> => {
58-
if (options && options.clearState === true) {
74+
if (isClearState) {
5975
loggers.forEach((logger: Logger, index: number) => {
6076
Logger.injectLambdaContextAfterOrOnError(
6177
logger,

‎packages/logger/tests/unit/middleware/middy.test.ts

+59
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
ContextExamples as dummyContext,
88
Events as dummyEvent,
99
} from '@aws-lambda-powertools/commons';
10+
import { cleanupMiddlewares } from '@aws-lambda-powertools/commons/lib/middleware';
1011
import {
1112
ConfigServiceInterface,
1213
EnvironmentVariablesService,
@@ -197,6 +198,64 @@ describe('Middy middleware', () => {
197198
persistentAttribsBeforeInvocation
198199
);
199200
});
201+
202+
test('when enabled, and another middleware returns early, it still clears the state', async () => {
203+
// Prepare
204+
const logger = new Logger({
205+
logLevel: 'DEBUG',
206+
});
207+
const loggerSpy = jest.spyOn(logger['console'], 'debug');
208+
const myCustomMiddleware = (): middy.MiddlewareObj => {
209+
const before = async (
210+
request: middy.Request
211+
): Promise<undefined | string> => {
212+
// Return early on the second invocation
213+
if (request.event.idx === 1) {
214+
// Cleanup Powertools resources
215+
await cleanupMiddlewares(request);
216+
217+
// Then return early
218+
return 'foo';
219+
}
220+
};
221+
222+
return {
223+
before,
224+
};
225+
};
226+
const handler = middy(
227+
(
228+
event: typeof dummyEvent.Custom.CustomEvent & { idx: number }
229+
): void => {
230+
// Add a key only at the first invocation, so we can check that it's cleared
231+
if (event.idx === 0) {
232+
logger.appendKeys({
233+
details: { user_id: '1234' },
234+
});
235+
}
236+
logger.debug('This is a DEBUG log');
237+
}
238+
)
239+
.use(injectLambdaContext(logger, { clearState: true }))
240+
.use(myCustomMiddleware());
241+
242+
// Act
243+
await handler({ ...event, idx: 0 }, context);
244+
await handler({ ...event, idx: 1 }, context);
245+
246+
// Assess
247+
const persistentAttribsAfterInvocation = {
248+
...logger.getPersistentLogAttributes(),
249+
};
250+
expect(persistentAttribsAfterInvocation).toEqual({});
251+
// Only one log because the second invocation returned early
252+
// from the custom middleware
253+
expect(loggerSpy).toBeCalledTimes(1);
254+
expect(loggerSpy).toHaveBeenNthCalledWith(
255+
1,
256+
expect.stringContaining('"details":{"user_id":"1234"}')
257+
);
258+
});
200259
});
201260

202261
describe('Feature: log event', () => {

0 commit comments

Comments
 (0)
Please sign in to comment.