Bugsnag-js: Update Example for Next.js

Created on 21 Apr 2020  Â·  6Comments  Â·  Source: bugsnag/bugsnag-js

Can you guys update your example to include a custom express.js server? The Next.js example you have is too trivial for real world situations so it'd be much more helpful to show how to use bugsnag in cases where you'd have custom routes being served by express. (I know that API routes exist now. but they didn't exist before so it'd be nice to show case common use cases within Next.js)

We're currently using bugsnag with an express server + next.js setup and it seems to not be working 100% of the time. So I'd like to see a recommended approach on how to do something like this.

Most helpful comment

I’d like to second this 🙏

The existing example seems to rely on a feature of Next that provides different environment variables for the server and client. It’s clever, but Next seems to have changed a lot recently, and ~that feature might not exist anymore (or it maybe it’s just deprecated/undocumented)~ it appears to have all sorts of caveats around serverless targets, automatic static optimization, etc.

Some questions I had that would be great to cover in the example:

  • How to handle providing keys to the Bugsnag client(s) if the Next config doesn’t (or will not shortly) support differentiating between server and client?
  • How to properly wrap API routes—there doesn’t seem to be a “root” that middleware can be added to, so each API route will probably need to be wrapped with a connect-like middleware?
  • Pages can be client-rendered, server-rendered, statically generated, statically generated on-the-fly, etc. and I’m unsure what or where I need to trap exceptions to handle all of those and how I need to trap them such that the exceptions go to the right Bugsnag app with the right app type'

I can sort of muddle through and figure out some of this but I’m not confident I’d get it right, so it’d be great to have a definitive reference. Thanks!

All 6 comments

Hi @lifeiscontent thanks for the report. We will look at updating the example app.

I’d like to second this 🙏

The existing example seems to rely on a feature of Next that provides different environment variables for the server and client. It’s clever, but Next seems to have changed a lot recently, and ~that feature might not exist anymore (or it maybe it’s just deprecated/undocumented)~ it appears to have all sorts of caveats around serverless targets, automatic static optimization, etc.

Some questions I had that would be great to cover in the example:

  • How to handle providing keys to the Bugsnag client(s) if the Next config doesn’t (or will not shortly) support differentiating between server and client?
  • How to properly wrap API routes—there doesn’t seem to be a “root” that middleware can be added to, so each API route will probably need to be wrapped with a connect-like middleware?
  • Pages can be client-rendered, server-rendered, statically generated, statically generated on-the-fly, etc. and I’m unsure what or where I need to trap exceptions to handle all of those and how I need to trap them such that the exceptions go to the right Bugsnag app with the right app type'

I can sort of muddle through and figure out some of this but I’m not confident I’d get it right, so it’d be great to have a definitive reference. Thanks!

I disagree completely. Next.js is constantly moving in a direction that aims to eliminate the need for any custom server ever. It seems weird to try to cover every conceivable configuration.

What I _would_ like to see though, is an explanation of why this error shows up in the example (or a fix):
[bugsnag] Bugsnag.start() was called more than once. Ignoring.

@kylemh it's because you need to do the following:

if (!Bugsnag._client) {
  Bugsnag.start({...});
}

Next.js runs this code more than once so you need to first ask Bugsnag if its client has already been initialized.

on your note, Next.js is severely lacking in implementing any of the common middlewares in the node.js ecosystem. They don't focus on it because they handle most of it for you through vercel. But if you're not on vercel, you don't have things like frameguard, CSP policies, etc which make it easy to hack an application running on Next.js.

regardless of your opinion, it's in bugsnag best interest to share a wide array of examples so their customers can have confidence implementing their tools with ease.

Thanks for the fix. I'll add it via a PR here.

I think it's in Bugsnag's best interest to focus on documentation they control rather than specific middleware or providers you leverage. Maintaining best practices based on all the different ways you can deploy your application and customize it (via a manner in which Next.js specifically advises against... many times), seems folly and untenable.

Thanks to everyone for all the input into this issue. After some investigation, we have decided to revisit updating this example following some planned improvements to the notifier.

The examples we provide are a supplement to the docs and aim to exhibit the simplest integration with the framework. It is infeasible to cover every conceivable configuration (especially so with next.js). Both a custom express.js server and the new API routes are, I think, too niche to be included in the next.js example.

Here are some pointers I found during my investigation that I hope will answer a number of the questions raised in this discussion:

Custom express server

For a custom express server, the express integration guide docs are a good start.

See here for what I came up with during the investigation.

How to handle providing keys to the Bugsnag client(s) if the Next config doesn’t (or will not shortly) support differentiating between server and client?

See here.

How to properly wrap API routes?

there doesn’t seem to be a “root” that middleware can be added to, so each API route will probably need to be wrapped with a connect-like middleware?

This is what I found too. See here. I'm not sure there is a better way. It seems the API routes are designed to be used within the vercel ecosystem where typical middleware functionality is handled external to the next.js application.

Pages can be client-rendered, server-rendered, statically generated, statically generated on-the-fly, etc. and I’m unsure what or where I need to trap exceptions to handle all of those and how I need to trap them such that the exceptions go to the right Bugsnag app with the right app type

This is where planned improvements to the notifier will help. Right now, if you want to forward errors caught in the next.js error handler, you'll need to make use of the private API. See here for an example.

In terms of how this can be done in next.js, a combination of this and this should do the trick, until the aforementioned notifier improvements are ready.

As pointed out, pages can be "client-rendered, server-rendered, statically generated, statically generated on-the-fly, etc." As with custom express servers and API routes, it might not be feasible to include all of the approaches in a single example. We will endevaour to target the primary use case when we revisit the example.

What I would like to see though, is an explanation of why this error shows up in the example (or a fix): [bugsnag] Bugsnag.start() was called more than once. Ignoring.

As @lifeiscontent points out, next.js actually executes the code multiple times, including during the build step, and it does not appear to reset modules in between subsequent runs. This means that as next.js runs the Bugsnag.start code for a second time (even though you only wrote it once and might expect it to only run once in a normal node/JavaScript environment) the internal _client instance is populated from the previous run of it, hence the warning.

More on that in the PR description: https://github.com/bugsnag/bugsnag-js/pull/885

Was this page helpful?
0 / 5 - 0 ratings