Skip to content

Commit 51a0cf0

Browse files
authored
fix(aws-serverless): Prevent crash in isPromiseAllSettledResult with null/undefined array elements (#19346)
Added a guard against null/undefined elements in isPromiseAllSettledResult which caused TypeError: Cannot convert undefined or null to object when captureAllSettledReasons: true and the Lambda handler returned an array containing nullish values. closes #19344
1 parent c1f83b7 commit 51a0cf0

2 files changed

Lines changed: 26 additions & 0 deletions

File tree

packages/aws-serverless/src/sdk.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ export interface WrapperOptions {
4444
function isPromiseAllSettledResult<T>(result: T[]): boolean {
4545
return result.every(
4646
v =>
47+
v != null &&
48+
typeof v === 'object' &&
4749
Object.prototype.hasOwnProperty.call(v, 'status') &&
4850
(Object.prototype.hasOwnProperty.call(v, 'value') || Object.prototype.hasOwnProperty.call(v, 'reason')),
4951
);

packages/aws-serverless/test/sdk.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,30 @@ describe('AWSLambda', () => {
191191
expect(mockCaptureException).toHaveBeenNthCalledWith(2, error2, expect.any(Function));
192192
expect(mockCaptureException).toBeCalledTimes(2);
193193
});
194+
195+
test('captureAllSettledReasons does not throw on array with null elements', async () => {
196+
const handler = () => Promise.resolve([null]);
197+
const wrappedHandler = wrapHandler(handler, { captureAllSettledReasons: true });
198+
await expect(wrappedHandler(fakeEvent, fakeContext, fakeCallback)).resolves.toEqual([null]);
199+
expect(mockCaptureException).toBeCalledTimes(0);
200+
});
201+
202+
test('captureAllSettledReasons does not throw on array with undefined elements', async () => {
203+
const handler = () => Promise.resolve([undefined]);
204+
const wrappedHandler = wrapHandler(handler, { captureAllSettledReasons: true });
205+
await expect(wrappedHandler(fakeEvent, fakeContext, fakeCallback)).resolves.toEqual([undefined]);
206+
expect(mockCaptureException).toBeCalledTimes(0);
207+
});
208+
209+
test('captureAllSettledReasons does not throw on mixed array with null and settled results', async () => {
210+
const handler = () => Promise.resolve([null, { status: 'rejected', reason: new Error() }]);
211+
const wrappedHandler = wrapHandler(handler, { captureAllSettledReasons: true });
212+
await expect(wrappedHandler(fakeEvent, fakeContext, fakeCallback)).resolves.toEqual([
213+
null,
214+
{ status: 'rejected', reason: expect.any(Error) },
215+
]);
216+
expect(mockCaptureException).toBeCalledTimes(0);
217+
});
194218
});
195219

196220
describe('wrapHandler() on sync handler', () => {

0 commit comments

Comments
 (0)