serverless-express icon indicating copy to clipboard operation
serverless-express copied to clipboard

Unhandled Promise Rejection on ALB event

Open repl-ullas-ml opened this issue 1 year ago • 2 comments

Given an ALB event with multiValueQueryStringParameters but one of the value fails decodeURIComponent , the promise isnt handled at all. Expectation is that it should return an error and consumers treat that error

https://github.com/CodeGenieApp/serverless-express/blob/1376bd01e29f6bcf911f86a2b17a5cb85b2844ec/src/event-sources/aws/alb.js#L40 https://github.com/CodeGenieApp/serverless-express/blob/1376bd01e29f6bcf911f86a2b17a5cb85b2844ec/src/event-sources/aws/alb.js#L17

The below test wont even report the failure since the promise is left unhandled

  test('serverlessExpressInstance should throw', async () => {
    const multiValueQueryStringParameters = { etype: ['odp'], passurl: ['/category/'], template: ['../../../../../../../../../etc/passwd%%0000.html'] }

    const event = makeEvent({
      eventSourceName: 'alb',
      path: '/',
      httpMethod: 'GET',
      multiValueQueryStringParameters
    })
    await expect(serverlessExpressInstance(event)).toThrow('some')
  })

Screenshot 2024-04-23 at 11 34 20 AM

repl-ullas-ml avatar Apr 23 '24 17:04 repl-ullas-ml

Thanks for the report. Serverless Express catches errors and returns to a response to the event source with the error in a format expected by the event source. For example, API Gateway expects a statusCode so it returns 500 along with the error. This is usually what you want, since if the Lambda throws an error, API Gateway returns a different error to the client. See:

https://github.com/CodeGenieApp/serverless-express/blob/mainline/src/configure.js#L72-L95 which catches the error, and

https://github.com/CodeGenieApp/serverless-express/blob/mainline/src/transport.js#L62-L80 which determines how to respond. Note line 63 ALB is included in the list of services that will include a response format rather than throwing the error.

If you really want to throw an error, you can do something like const response = await serverlessExpressInstance(event) and inspect it for a 500, and then throw.

brettstack avatar Apr 23 '24 23:04 brettstack