Skip to content

Commit 2a37745

Browse files
author
Fabiana Severin
committed
Adding warning for callback handlers
1 parent 34b48f1 commit 2a37745

File tree

4 files changed

+100
-0
lines changed

4 files changed

+100
-0
lines changed

src/UserFunction.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,10 +311,16 @@ module.exports.isHandlerFunction = function (value) {
311311
return typeof value === 'function';
312312
};
313313

314+
function _isAsync(handlerFunc) {
315+
return handlerFunc.constructor.name === 'AsyncFunction';
316+
}
317+
314318
module.exports.getHandlerMetadata = function (handlerFunc) {
315319
return {
316320
streaming: _isHandlerStreaming(handlerFunc),
317321
highWaterMark: _highWaterMark(handlerFunc),
322+
isAsync: _isAsync(handlerFunc),
323+
argsNum: handlerFunc.length,
318324
};
319325
};
320326

src/WarningForCallbackHandlers.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
'use strict';
7+
8+
const shouldWarnOnCallbackFunctionUse = (metadata) => {
9+
return (
10+
process.env.AWS_LAMBDA_NODEJS_DISABLE_CALLBACK_WARNING === undefined &&
11+
metadata !== undefined &&
12+
metadata.argsNum == 3 &&
13+
metadata.isAsync == false &&
14+
metadata.streaming == false
15+
);
16+
};
17+
18+
module.exports.checkForDeprecatedCallback = function (metadata) {
19+
if (shouldWarnOnCallbackFunctionUse(metadata)) {
20+
console.warn(
21+
`AWS Lambda plans to remove support for callback-based function handlers starting with Node.js 24. You will need to update this function to use an async handler to use Node.js 24 or later. For more information and to provide feedback on this change, see https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/issues/137. To disable this warning, set the AWS_LAMBDA_NODEJS_DISABLE_CALLBACK_WARNING environment variable.`,
22+
);
23+
}
24+
};

src/index.mjs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const UserFunction = require('./UserFunction.js');
1111
const Errors = require('./Errors.js');
1212
const BeforeExitListener = require('./BeforeExitListener.js');
1313
const LogPatch = require('./LogPatch');
14+
const { checkForDeprecatedCallback } = require('./WarningForCallbackHandlers');
1415

1516
export async function run(appRootOrHandler, handler = '') {
1617
LogPatch.patchConsole();
@@ -44,6 +45,7 @@ export async function run(appRootOrHandler, handler = '') {
4445
: await UserFunction.load(appRootOrHandler, handler);
4546

4647
const metadata = UserFunction.getHandlerMetadata(handlerFunc);
48+
checkForDeprecatedCallback(metadata);
4749
new Runtime(
4850
client,
4951
handlerFunc,
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
'use strict';
7+
8+
require('should');
9+
10+
let { captureStream, consoleSnapshot } = require('./LoggingGlobals');
11+
12+
let {
13+
checkForDeprecatedCallback,
14+
} = require('../../src/WarningForCallbackHandlers.js');
15+
16+
let LogPatch = require('lambda-runtime/LogPatch');
17+
const UserFunction = require('lambda-runtime/UserFunction.js');
18+
19+
const path = require('path');
20+
const TEST_ROOT = path.join(__dirname, '../');
21+
const HANDLERS_ROOT = path.join(TEST_ROOT, 'handlers');
22+
23+
describe('Formatted Error Logging', () => {
24+
let restoreConsole = consoleSnapshot();
25+
let capturedStdout = captureStream(process.stdout);
26+
27+
beforeEach(
28+
'delete env var',
29+
() => delete process.env.AWS_LAMBDA_NODEJS_DISABLE_CALLBACK_WARNING,
30+
);
31+
beforeEach('capture stdout', () => capturedStdout.hook());
32+
beforeEach('apply console patch', () => LogPatch.patchConsole());
33+
afterEach('remove console patch', () => restoreConsole());
34+
afterEach('unhook stdout', () => capturedStdout.unhook());
35+
36+
const expectedString =
37+
'AWS Lambda plans to remove support for callback-based function handlers';
38+
39+
const tests = [
40+
{ args: [false, 'isAsyncCallback.handler'], expected: true },
41+
{ args: [true, 'isAsyncCallback.handler'], expected: false },
42+
{ args: [false, 'isAsync.handlerAsync'], expected: false },
43+
{ args: [true, 'isAsync.handlerAsync'], expected: false },
44+
{ args: [false, 'defaultHandler.default'], expected: false },
45+
{ args: [true, 'defaultHandler.default'], expected: false },
46+
];
47+
48+
tests.forEach(({ args, expected }) => {
49+
const shouldDeclareEnv = args[0];
50+
const handler = args[1];
51+
it(`When AWS_LAMBDA_NODEJS_DISABLE_CALLBACK_WARNING=${shouldDeclareEnv} expecting ${
52+
expected ? 'no ' : ''
53+
}warning logs for handler ${handler}`, async () => {
54+
if (shouldDeclareEnv) {
55+
process.env.AWS_LAMBDA_NODEJS_DISABLE_CALLBACK_WARNING = 1;
56+
}
57+
const handlerFunc = await UserFunction.load(HANDLERS_ROOT, handler);
58+
const metadata = UserFunction.getHandlerMetadata(handlerFunc);
59+
60+
checkForDeprecatedCallback(metadata);
61+
if (expected) {
62+
capturedStdout.captured().should.containEql(expectedString);
63+
} else {
64+
capturedStdout.captured().should.not.containEql(expectedString);
65+
}
66+
});
67+
});
68+
});

0 commit comments

Comments
 (0)