Repository: serverless/dashboard (language: python)

Issue:
AWS Lambda SDK: Report `response` in all cases
_Depends on https://github.com/serverless/console/pull/286_

- Upgrade `@serverless/sdk-schema` to v0.13
- Report `response` in dev mode all cases


Discussion / hints:

Fix patch:
diff --git a/node/packages/aws-lambda-sdk/instrument/index.js b/node/packages/aws-lambda-sdk/instrument/index.js
index d30772e06..c64e16c0f 100644
--- a/node/packages/aws-lambda-sdk/instrument/index.js
+++ b/node/packages/aws-lambda-sdk/instrument/index.js
@@ -73,7 +73,7 @@ const reportResponse = async (response, context, endTime) => {
     spanId: Buffer.from(awsLambdaSpan.id),
     requestId: context.awsRequestId,
     timestamp: toProtobufEpochTimestamp(endTime),
-    body: responseString,
+    body: responseString || undefined,
     origin: 2,
   });
   const payloadBuffer = (serverlessSdk._lastResponseBuffer =


Test patch:
diff --git a/node/packages/aws-lambda-sdk/test/fixtures/lambdas/callback-no-result.js b/node/packages/aws-lambda-sdk/test/fixtures/lambdas/callback-no-result.js
new file mode 100644
index 000000000..6d27cccdd
--- /dev/null
+++ b/node/packages/aws-lambda-sdk/test/fixtures/lambdas/callback-no-result.js
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports.handler = (event, context, callback) => callback();
diff --git a/node/packages/aws-lambda-sdk/test/integration/index.test.js b/node/packages/aws-lambda-sdk/test/integration/index.test.js
index 49700c067..c81b10266 100644
--- a/node/packages/aws-lambda-sdk/test/integration/index.test.js
+++ b/node/packages/aws-lambda-sdk/test/integration/index.test.js
@@ -267,6 +267,22 @@ describe('integration', function () {
     }
   };
 
+  const devModeConfiguration = {
+    configuration: {
+      Environment: {
+        Variables: {
+          AWS_LAMBDA_EXEC_WRAPPER: '/opt/sls-sdk-node/exec-wrapper.sh',
+          SLS_ORG_ID: process.env.SLS_ORG_ID,
+          SLS_DEV_MODE_ORG_ID: process.env.SLS_ORG_ID,
+          SLS_SDK_DEBUG: '1',
+        },
+      },
+    },
+    deferredConfiguration: () => ({
+      Layers: [coreConfig.layerInternalArn, coreConfig.layerExternalArn],
+    }),
+  };
+
   const useCasesConfig = new Map([
     [
       'esm-callback/index',
@@ -1085,24 +1101,7 @@ describe('integration', function () {
             {
               config: { configuration: { Runtime: 'nodejs12.x' } },
               variants: new Map([
-                [
-                  'dev-mode',
-                  {
-                    configuration: {
-                      Environment: {
-                        Variables: {
-                          AWS_LAMBDA_EXEC_WRAPPER: '/opt/sls-sdk-node/exec-wrapper.sh',
-                          SLS_ORG_ID: process.env.SLS_ORG_ID,
-                          SLS_DEV_MODE_ORG_ID: process.env.SLS_ORG_ID,
-                          SLS_SDK_DEBUG: '1',
-                        },
-                      },
-                    },
-                    deferredConfiguration: () => ({
-                      Layers: [coreConfig.layerInternalArn, coreConfig.layerExternalArn],
-                    }),
-                  },
-                ],
+                ['dev-mode', devModeConfiguration],
                 ['regular', {}],
               ]),
             },
@@ -1112,24 +1111,7 @@ describe('integration', function () {
             {
               config: { configuration: { Runtime: 'nodejs14.x' } },
               variants: new Map([
-                [
-                  'dev-mode',
-                  {
-                    configuration: {
-                      Environment: {
-                        Variables: {
-                          AWS_LAMBDA_EXEC_WRAPPER: '/opt/sls-sdk-node/exec-wrapper.sh',
-                          SLS_ORG_ID: process.env.SLS_ORG_ID,
-                          SLS_DEV_MODE_ORG_ID: process.env.SLS_ORG_ID,
-                          SLS_SDK_DEBUG: '1',
-                        },
-                      },
-                    },
-                    deferredConfiguration: () => ({
-                      Layers: [coreConfig.layerInternalArn, coreConfig.layerExternalArn],
-                    }),
-                  },
-                ],
+                ['dev-mode', devModeConfiguration],
                 ['regular', {}],
               ]),
             },
@@ -1139,24 +1121,7 @@ describe('integration', function () {
             {
               config: { configuration: { Runtime: 'nodejs16.x' } },
               variants: new Map([
-                [
-                  'dev-mode',
-                  {
-                    configuration: {
-                      Environment: {
-                        Variables: {
-                          AWS_LAMBDA_EXEC_WRAPPER: '/opt/sls-sdk-node/exec-wrapper.sh',
-                          SLS_ORG_ID: process.env.SLS_ORG_ID,
-                          SLS_DEV_MODE_ORG_ID: process.env.SLS_ORG_ID,
-                          SLS_SDK_DEBUG: '1',
-                        },
-                      },
-                    },
-                    deferredConfiguration: () => ({
-                      Layers: [coreConfig.layerInternalArn, coreConfig.layerExternalArn],
-                    }),
-                  },
-                ],
+                ['dev-mode', devModeConfiguration],
                 ['regular', {}],
               ]),
             },
@@ -1226,6 +1191,20 @@ describe('integration', function () {
         },
       },
     ],
+    [
+      'callback-no-result',
+      {
+        variants: new Map([
+          ['v12', { config: { configuration: { Runtime: 'nodejs12.x' } } }],
+          ['v14', { config: { configuration: { Runtime: 'nodejs14.x' } } }],
+          ['v16', { config: { configuration: { Runtime: 'nodejs16.x' } } }],
+        ]),
+        config: Object.assign({
+          isCustomResponse: true,
+          devModeConfiguration,
+        }),
+      },
+    ],
   ]);
 
   const testVariantsConfig = resolveTestVariantsConfig(useCasesConfig);
@@ -1251,7 +1230,11 @@ describe('integration', function () {
       const { expectedOutcome } = testConfig;
       const { invocationsData } = testResult;
       if (expectedOutcome === 'success' || expectedOutcome === 'error:handled') {
-        if (expectedOutcome === 'success' && !testConfig.isAsyncInvocation) {
+        if (
+          expectedOutcome === 'success' &&
+          !testConfig.isAsyncInvocation &&
+          !testConfig.isCustomResponse
+        ) {
           for (const { responsePayload } of invocationsData) {
             expect(responsePayload.raw).to.equal('"ok"');
           }
diff --git a/node/packages/aws-lambda-sdk/test/unit/internal-extension/index.test.js b/node/packages/aws-lambda-sdk/test/unit/internal-extension/index.test.js
index 2ad7e119e..d4afd12a5 100644
--- a/node/packages/aws-lambda-sdk/test/unit/internal-extension/index.test.js
+++ b/node/packages/aws-lambda-sdk/test/unit/internal-extension/index.test.js
@@ -100,7 +100,7 @@ const handleInvocation = async (handlerModuleName, options = {}) => {
   } else {
     if (outcome.error) throw outcome.error;
     if (options.isApiEndpoint) expect(JSON.parse(outcome.result.body)).to.equal('ok');
-    else expect(outcome.result).to.equal('ok');
+    else if (!options.isCustomReponse) expect(outcome.result).to.equal('ok');
 
     expect(lambdaSpanTags.aws.lambda.outcome).to.equal(1);
   }
@@ -162,7 +162,7 @@ describe('internal-extension/index.test.js', () => {
       isApiEndpoint: true,
       payload: {
         resource: '/some-path/{param}',
-        path: '/some-path/some-param',
+        path: '/some-path/some.-param',
         httpMethod: 'POST',
         headers: {
           'Accept': '*/*',
@@ -795,7 +795,7 @@ describe('internal-extension/index.test.js', () => {
 
   describe('dev mode', () => {
     let server;
-    const payloads = [];
+    let payloads = [];
     before(() => {
       const { TracePayload } = require('@serverless/sdk-schema/dist/trace');
       const { RequestResponse } = require('@serverless/sdk-schema/dist/request_response');
@@ -822,11 +822,16 @@ describe('internal-extension/index.test.js', () => {
       server.listen(2773);
     });
 
+    afterEach(() => {
+      payloads = [];
+    });
+
     after(() => {
       delete process.env.SLS_DEV_MODE_ORG_ID;
       server.close();
     });
-    it('should support dev mode', async () => {
+
+    it('should provide general support', async () => {
       const {
         trace: {
           input: { spans },
@@ -919,5 +924,40 @@ describe('internal-extension/index.test.js', () => {
         },
       ]);
     });
+
+    it('should support no return functions', async () => {
+      await handleInvocation('callback-no-result', { isCustomReponse: true });
+
+      expect(
+        payloads.map(([type, payload]) => {
+          switch (type) {
+            case 'request-response':
+              return { type, origin: payload.origin };
+            case 'trace':
+              return {
+                type,
+                spans: payload.spans.map(({ name, input, output }) => ({ name, input, output })),
+              };
+            default:
+              throw new Error('Unexpected');
+          }
+        })
+      ).to.deep.equal([
+        {
+          type: 'trace',
+          spans: [{ name: 'aws.lambda.initialization', input: undefined, output: undefined }],
+        },
+        { type: 'request-response', origin: 1 },
+
+        { type: 'request-response', origin: 2 },
+        {
+          type: 'trace',
+          spans: [
+            { name: 'aws.lambda.invocation', input: undefined, output: undefined },
+            { name: 'aws.lambda', input: undefined, output: undefined },
+          ],
+        },
+      ]);
+    });
   });
 });