dherault / serverless-offline

Emulate AWS λ and API Gateway locally when developing your Serverless project
MIT License
5.2k stars 793 forks source link

Cryptic error message when returning non-serializable data #1650

Open Hurtak opened 1 year ago

Hurtak commented 1 year ago

Bug Report

Current Behavior

When you return non-serializible data from the lambda, serverless prints very cryptic error message with no user code stack trace and 0 information

Example code:

export const handler = async () => ({
  ok: "serializable",
  noOk: () => {}, // this line breaks the whole lambda
});

Error when caaling this endpoint:

GET /dev/example-fn (λ: example-fn)
✖ Uncaught exception
Environment: darwin, node 16.19.0, framework 3.24.1 (local), plugin 6.2.2, SDK 4.3.2
Credentials: Local, "default" profile
Docs:        docs.serverless.com
Support:     forum.serverless.com
Bugs:        github.com/serverless/serverless/issues

Error:
Error [ERR_UNHANDLED_ERROR]: Unhandled error. ({})
    at __node_internal_captureLargerStackTrace (node:internal/errors:478:5)
    at new NodeError (node:internal/errors:387:5)
    at Worker.emit (node:events:502:17)
    at Worker.emit (node:domain:489:12)
    at Worker.[kOnErrorMessage] (node:internal/worker:298:10)
    at Worker.[kOnMessage] (node:internal/worker:309:37)
    at MessagePort.<anonymous> (node:internal/worker:205:57)
    at MessagePort.[nodejs.internal.kHybridDispatch] (node:internal/event_target:736:20)
    at MessagePort.exports.emitMessage (node:internal/per_context/messageport:23:28)

I traced it down to this TODO line of code in serverless-offline https://github.com/dherault/serverless-offline/blob/5b198a752c8cfdcbde5e3eb7e041a64ac3626289/src/lambda/handler-runner/worker-thread-runner/workerThreadHelper.js#L29-L30

Expected behavior/code

Probably one of the two would be good

Misc

I was not that familiar with Serverless (using it for a few weeks only) so I have spent a lot of time figuring this one out (probably around 10 hours) - I had no idea where to look for what was wrong, and I had to connect to debugger and step through serverless-offline code to figure this out. So having good error message in this place could probably be big usability/accessibility win for future versions.

seanmurph commented 3 months ago

I've been running into this constantly. The simplest solution is to change the line @Hurtak called out:

  port.postMessage(JSON.parse(JSON.stringify(result)))

Not pushing a PR as there's probably a better way to serialize, but it gets the job done for me.