bugsnag-js icon indicating copy to clipboard operation
bugsnag-js copied to clipboard

Reporting handled errors fails on Vercel serverless functions

Open reegodev opened this issue 4 years ago • 10 comments

Reporting handled errors fails on Vercel serverless functions

When using Bugsnag.notify in serverless functions on Vercel, the process is terminated before Bugsnag client can effectively send the notification, resulting in a loss of events.

Sample code

This naive implementation fails to report errors because, as mentioned above, the Vercel runtime kills the process before notify is done sending.

const Bugsnag = require('@bugsnag/js')

Bugsnag.start({
  apiKey: process.env.BUGSNAG_API_KEY,
})

module.exports = async (req, res) => {
  try {
    throw new Error('A test error')
  } catch (error) {
    Bugsnag.notify(error)
    return res.status(500).send('Error')
  }
  
  return res.send('Success')
}

The only workaround we could find was to create a helper function that returns a promise and resolves the promise when Bugsnag.notify is done sending.

const Bugsnag = require('@bugsnag/js')
Bugsnag.start('API_KEY')

const notifyError = (error) => new Promise((resolve) => Bugsnag.notify(error, null, resolve))

Bugsnag.start({
  apiKey: process.env.BUGSNAG_API_KEY,
})

module.exports = async (req, res) => {
  try {
    throw new Error('A test error')
  } catch (error) {
    await notifyError(error)
    return res.status(500).send('Error')
  }
  
  return res.send('Success')
}

Using the awsLambda plugin does not help. Although Vercel serverless functions have a different signature they always receive two arguments, so the lambda plugin seems to be compatible. However the function logs report this:

[GET] /api/bugsnag
11:51:07:36
2021-04-16T09:51:07.424Z	fb2d826a-561e-46a5-9d9f-c1cca572eea0	ERROR	[bugsnag] Delivery may be unsuccessful: flush timed out after 2000ms
2021-04-16T09:51:07.448Z	e2498778-cfea-4a5a-aad8-3aa3ab13d844	ERROR	[bugsnag] Session failed to send…
Error: Client network socket disconnected before secure TLS connection was established
    at connResetException (internal/errors.js:607:14)
    at TLSSocket.onConnectEnd (_tls_wrap.js:1544:19)
    at TLSSocket.emit (events.js:327:22)
    at TLSSocket.EventEmitter.emit (domain.js:467:12)
    at endReadableNT (internal/streams/readable.js:1327:12)
    at processTicksAndRejections (internal/process/task_queues.js:80:21) Error: Client network socket disconnected before secure TLS connection was established
    at connResetException (internal/errors.js:607:14)
    at TLSSocket.onConnectEnd (_tls_wrap.js:1544:19)
    at TLSSocket.emit (events.js:327:22)
    at TLSSocket.EventEmitter.emit (domain.js:467:12)
    at endReadableNT (internal/streams/readable.js:1327:12)
    at processTicksAndRejections (internal/process/task_queues.js:80:21) {
  code: 'ECONNRESET',
  path: null,
  host: 'sessions.bugsnag.com',
  port: 443,
  localAddress: undefined
}

Is there any chance to make Bugsnag.notify return a promise if the third argument is omitted, as with most Node libraries that support both promises and callbacks? I'd be happy to provide a PR if you agree on the solution.

reegodev avatar Apr 15 '21 17:04 reegodev

Hi @reegodev,

The AWS Lambda plugin should wait for any Bugsnag.notify() calls to be delivered. Could you tell me a bit more about the problems you encountered when trying to use that? Perhaps you could share how you configured your code with the plugin?

johnkiely1 avatar Apr 16 '21 08:04 johnkiely1

Hi @johnkiely1 , after testing a repro i found out that its actually only Vercel functions to have this problem, the awsLambda plugins works correctly on Netlify, so i updated the issue. Sorry about that.

I created a repo you can deploy to Vercel with the button found in the readme: https://github.com/reegodev/test-bugsnag-serverless

You can trigger the error with curl <YOUR ENDPOINT>/api/bugsnag

reegodev avatar Apr 16 '21 10:04 reegodev

Hi @reegodev,

From your logs it looks like the problem is that delivery times out:

Delivery may be unsuccessful: flush timed out after 2000ms

You could try increasing the flushTimeoutMs to allow it to wait longer —https://docs.bugsnag.com/platforms/javascript/aws-lambda/#flushtimeoutms

Although this is a reasonable amount of time to wait so perhaps theres an underlying network problem at fault?

There’s also an AWS Lambda API that you can opt in to, which might have a better chance of success: https://vercel.com/docs/runtimes#advanced-usage/advanced-node-js-usage/aws-lambda-api

Ultimately however we don't officially support Vercel functions as yet so it may be the case that the above suggestions will still have no effect.

Do let us know how you get on. Thanks

johnkiely1 avatar Apr 16 '21 13:04 johnkiely1

Thanks, @johnkiely1 , increasing the timeout did not solve the problem, i tried with 10 seconds and received the same error.

Using the AWS Lambda API however did work. So i guess its just the custom Vercel function runtime that somehow blocks the AWS Lambda plugin. Is it worth mentioning in the AWS Lambda section of the docs that Vercel functions are only supported through the Lambda API format?

reegodev avatar Apr 16 '21 13:04 reegodev

@reegodev We're going to track this as a feature request for adding official support for Vercel serverless functions, but using the AWS Lambda API seems like a reasonable option in the meantime.

mattdyoung avatar Apr 21 '21 14:04 mattdyoung

Might be related to this issue: https://github.com/bugsnag/bugsnag-js/issues/1875

hansottowirtz avatar Dec 20 '22 14:12 hansottowirtz

@reegodev Did you ever find a solution to this? We're seeing theses errors with Bugsnag on Vercel with Next.js.

2023-05-22T22:39:23.893Z	63d97795-12a8-44f3-xxxx-ce59ec51770f	INFO	[bugsnag] Delivery may be unsuccessful: flush timed out after 2000ms
2023-05-22T22:39:23.896Z	3595a722-ef72-462c-xxxx-e25e83d42f24	INFO	[bugsnag] Session failed to send…
Error: Client network socket disconnected before secure TLS connection was established
    at connResetException (node:internal/errors:717:14)
    at TLSSocket.onConnectEnd (node:_tls_wrap:1595:19)
    at TLSSocket.emit (node:events:525:35)
    at TLSSocket.emit (node:domain:489:12)
    at endReadableNT (node:internal/streams/readable:1359:12)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21)

statico avatar May 22 '23 22:05 statico

@statico This is because Bugsnag doesn't correctly flush in the current request and then times out in the request that follows.

hansottowirtz avatar May 22 '23 23:05 hansottowirtz

@statico If I remember correctly we went with the Lambda API as suggested by @mattdyoung

reegodev avatar May 26 '23 11:05 reegodev