Skip to content

Commit 808cc79

Browse files
committed
Flush buffer on uncaught error in middy middleware
1 parent b234e4d commit 808cc79

File tree

2 files changed

+59
-8
lines changed

2 files changed

+59
-8
lines changed

packages/logger/src/middleware/middy.ts

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import type {
44
MiddyLikeRequest,
55
} from '@aws-lambda-powertools/commons/types';
66
import { Logger } from '../Logger.js';
7+
import { UncaughtErrorLogMessage } from '../constants.js';
78
import type { InjectLambdaContextOptions } from '../types/Logger.js';
89

910
/**
@@ -76,13 +77,11 @@ const injectLambdaContext = (
7677
const setCleanupFunction = (request: MiddyLikeRequest): void => {
7778
request.internal = {
7879
...request.internal,
79-
[LOGGER_KEY]: injectLambdaContextAfterOrOnError,
80+
[LOGGER_KEY]: onAfter,
8081
};
8182
};
8283

83-
const injectLambdaContextBefore = async (
84-
request: MiddyLikeRequest
85-
): Promise<void> => {
84+
const onBefore = async (request: MiddyLikeRequest): Promise<void> => {
8685
for (const logger of loggers) {
8786
if (isResetStateEnabled) {
8887
setCleanupFunction(request);
@@ -99,18 +98,33 @@ const injectLambdaContext = (
9998
}
10099
};
101100

102-
const injectLambdaContextAfterOrOnError = async (): Promise<void> => {
101+
const onAfter = async (): Promise<void> => {
103102
if (isResetStateEnabled) {
104103
for (const logger of loggers) {
105104
logger.resetKeys();
106105
}
107106
}
107+
108+
for (const logger of loggers) {
109+
logger.clearBuffer();
110+
}
111+
};
112+
const onError = async ({ error }): Promise<void> => {
113+
if (options?.flushBufferOnUncaughtError) {
114+
for (const logger of loggers) {
115+
logger.flushBuffer();
116+
logger.error({
117+
message: UncaughtErrorLogMessage,
118+
error,
119+
});
120+
}
121+
}
108122
};
109123

110124
return {
111-
before: injectLambdaContextBefore,
112-
after: injectLambdaContextAfterOrOnError,
113-
onError: injectLambdaContextAfterOrOnError,
125+
before: onBefore,
126+
after: onAfter,
127+
onError,
114128
};
115129
};
116130

packages/logger/tests/unit/logBuffer.test.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import context from '@aws-lambda-powertools/testing-utils/context';
22
import type { Context } from 'aws-lambda';
3+
import middy from 'middy5';
34
import { type Mock, beforeEach, describe, expect, it, vi } from 'vitest';
45
import { Logger } from '../../src/Logger.js';
56
import { LogLevel, UncaughtErrorLogMessage } from '../../src/constants.js';
7+
import { injectLambdaContext } from '../../src/middleware/middy.js';
68
import type { ConstructorOptions } from '../../src/types/Logger.js';
79

810
describe('Buffer logs', () => {
@@ -227,6 +229,41 @@ describe('Buffer logs', () => {
227229
const lambda = new TestClass();
228230
const handler = lambda.handler.bind(lambda);
229231

232+
// Act & Assess
233+
await expect(() =>
234+
handler(
235+
{
236+
foo: 'bar',
237+
},
238+
context
239+
)
240+
).rejects.toThrow(new Error('This is an error'));
241+
expect(console.debug).toBeCalledTimes(1);
242+
expect(console.info).toBeCalledTimes(1);
243+
expect(console.error).toHaveLogged(
244+
expect.objectContaining({
245+
message: UncaughtErrorLogMessage,
246+
})
247+
);
248+
// If debug is called after info, it means it was buffered and then flushed
249+
expect(console.debug).toHaveBeenCalledAfter(console.info as Mock);
250+
// If error is called after debug, it means the buffer was flushed before the error log
251+
expect(console.debug).toHaveBeenCalledBefore(console.error as Mock);
252+
});
253+
it('flushes the buffer when an uncaught error is thrown in a middy', async () => {
254+
// Prepare
255+
const logger = new Logger({ logBufferOptions: { enabled: true } });
256+
257+
const handlerFn = async (_event: unknown, _context: Context) => {
258+
logger.debug('This is a log message');
259+
logger.info('This is an info message');
260+
throw new Error('This is an error');
261+
};
262+
263+
const handler = middy()
264+
.use(injectLambdaContext(logger, { flushBufferOnUncaughtError: true }))
265+
.handler(handlerFn);
266+
230267
// Act & Assess
231268
await expect(() =>
232269
handler(

0 commit comments

Comments
 (0)