Repository: serverless/serverless (JavaScript) — Bug Fix

Issue:
AWS Invoke Local handleError function does not return stack trace, just errorMessage and errorType
# This is a Bug Report

## Description

When using the `invoke local` command with an AWS Serverless project, when you get an error there is no stack trace.

**What does happen:**

```
$ node_modules/.bin/serverless invoke local -s dev -l --function testError
{
    "errorMessage": "Whoops",
    "errorType": "Error"
}
````

It would be preferable to have a stack trace, so you can figure out where your error is. 

**What should happen:**

```
{
    "errorMessage": "Whoops",
    "errorType": "Error",
    "stackTrace": [
        "Error: Whoops",
        "    at exports.testError (/home/test/data-etl/active/simpleTest.js:3:11)",
        "    at Promise (/home/test/data-etl/active/node_modules/serverless/lib/plugins/aws/invokeLocal/index.js:399:30)",
        "    at new Promise (<anonymous>)",
        "    at AwsInvokeLocal.invokeLocalNodeJs (/home/test/data-etl/active/node_modules/serverless/lib/plugins/aws/invokeLocal/index.js:353:12)",
        "    at AwsInvokeLocal.invokeLocal (/home/test/data-etl/active/node_modules/serverless/lib/plugins/aws/invokeLocal/index.js:131:19)",
        "    at AwsInvokeLocal.tryCatcher (/home/test/data-etl/active/node_modules/bluebird/js/release/util.js:16:23)",
        "    at Promise._settlePromiseFromHandler (/home/test/data-etl/active/node_modules/bluebird/js/release/promise.js:512:31)",
        "    at Promise._settlePromise (/home/test/data-etl/active/node_modules/bluebird/js/release/promise.js:569:18)",
        "    at Promise._settlePromiseCtx (/home/test/data-etl/active/node_modules/bluebird/js/release/promise.js:606:10)",
        "    at _drainQueueStep (/home/test/data-etl/active/node_modules/bluebird/js/release/async.js:142:12)",
        "    at _drainQueue (/home/test/data-etl/active/node_modules/bluebird/js/release/async.js:131:9)",
        "    at Async._drainQueues (/home/test/data-etl/active/node_modules/bluebird/js/release/async.js:147:5)",
        "    at Immediate.Async.drainQueues (/home/test/data-etl/active/node_modules/bluebird/js/release/async.js:17:14)",
        "    at runCallback (timers.js:763:18)",
        "    at tryOnImmediate (timers.js:734:5)",
        "    at processImmediate (timers.js:716:5)",
        "    at process.topLevelDomainCallback (domain.js:102:23)"
    ]
}
```

The file that catches the errors and outputs the message appears to be this one:
`/serverless/lib/plugins/aws/invokeLocal/index.js`

I would add that I am invoking a node 8.10 async handler function:
```
exports.testError = async function(data, lambdaContext) {
    throw new Error('Whoops')
    return 'test'
};
```

I have tested with Webpack and Babel removed, so they are not a factor here. It's just the AWS invokeLocal error handler.

Similar or dependent issues:
* #4309 - seems like the same bug, but there was confusion about Webpack being involved so it was closed (Webpack is in fact not involved)

## Additional Data

* ***Serverless Framework Version***: 1.36.2 (appears to be present in 1.37.1 too)
* ***Operating System***: Ubuntu 14.04
* ***Node / NPM Version***: v9.11.2 / 5.8.0
* ***Serverless Provider***: AWS

_Serverless Provider Config:_
```
provider:
  name: aws
  runtime: nodejs8.10
```



Discussion:

Resolving patch:
diff --git a/lib/plugins/aws/invokeLocal/index.js b/lib/plugins/aws/invokeLocal/index.js
index 91332030deb..bf32955ca42 100644
--- a/lib/plugins/aws/invokeLocal/index.js
+++ b/lib/plugins/aws/invokeLocal/index.js
@@ -329,6 +329,7 @@ class AwsInvokeLocal {
         errorResult = {
           errorMessage: err.message,
           errorType: err.constructor.name,
+          stackTrace: err.stack.split('\n'),
         };
       } else {
         errorResult = {


Test patch:
diff --git a/lib/plugins/aws/invokeLocal/index.test.js b/lib/plugins/aws/invokeLocal/index.test.js
index 4bd83d751b1..c8bba83f4bf 100644
--- a/lib/plugins/aws/invokeLocal/index.test.js
+++ b/lib/plugins/aws/invokeLocal/index.test.js
@@ -582,8 +582,11 @@ describe('AwsInvokeLocal', () => {
 
       awsInvokeLocal.invokeLocalNodeJs('fixture/handlerWithError', 'withError');
 
-      expect(serverless.cli.consoleLog.lastCall.args[0]).to.contain('"errorMessage": "failed"');
-      expect(serverless.cli.consoleLog.lastCall.args[0]).to.contain('"errorType": "Error"');
+      const logMessageContent = JSON.parse(serverless.cli.consoleLog.lastCall.args[0]);
+
+      expect(logMessageContent.errorMessage).to.equal('failed');
+      expect(logMessageContent.errorType).to.equal('Error');
+      expect(logMessageContent.stackTrace[0]).to.equal('Error: failed');
     });
 
     it('should log Error object if handler crashes at initialization', () => {