Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cloudflare Workers Support #637

Open
domharrington opened this issue Oct 30, 2019 · 25 comments
Open

Cloudflare Workers Support #637

domharrington opened this issue Oct 30, 2019 · 25 comments
Labels
backlog We hope to fix this feature/bug in the future feature request Request for a new feature

Comments

@domharrington
Copy link

Hey! I attempted to use Bugsnag within a Cloudflare Worker: https://www.cloudflare.com/products/cloudflare-workers/. This is like the Service Workers API, but built to run at the CDN layer instead of in a user's browser.

I attempted to bring in both @bugsnag/js (didn't work due to navigator not being set) and @bugsnag/node (didn't work due to no "fs" module). I also tried to use the unofficial https://github.com/jmshal/bugsnag-js-cloudflare-workers but this did not work either.

The way to compile workers is to use webpack + webworker target (https://webpack.js.org/configuration/target/#string), which complicates things even further.

I ended up with a solution that looks something like this (using @bugsnag/core/report + error-stack-parser, thanks to report.test.js in this repo! + your HTTP API):

const Report = require('@bugsnag/core/report');
const ErrorStackParser = require('error-stack-parser')

addEventListener('fetch', event => {
  event.passThroughOnException();

  event.respondWith(respond(event));
});

async function respond(event) {
  try {
    // Some more worker code that may error
    return fetch(event.request);
  } catch(e) {
    const report = new Report(e.name, e.message, ErrorStackParser.parse(e));
    report.updateMetaData('request', {
      method: event.request.method,
      url: event.request.url,
    });
    report.app = {
      id: 'name',
      version: '1.0.0',
    };
    console.log('Sending error to bugsnag', e.name, e.message, ErrorStackParser.parse(e), JSON.stringify(report));

    event.waitUntil(fetch('https://notify.bugsnag.com/', {
      method: 'POST',
      headers: {
        'Bugsnag-Api-Key': 'BUGSNAG_API_KEY',
      },
      body: JSON.stringify({
        notifier: {
          name: 'name',
          version: '1.0.0',
          url: 'https://example.com/',
        },
        events: [
          report,
        ],
      }),
    }))
  }
}

This seems to work, but would be great to have first class support for this!
Cheers

@bengourley
Copy link
Contributor

Hey Dom! 👋

We have service worker support on our internal backlog. It seems like supporting service workers would be the first step towards achieving this (removing reliance on parts of the browser environment that doesn't exist etc.) and then direct support for Cloudflare workers would be added via a plugin. I'll add that to the backlog too.

@bengourley bengourley added backlog We hope to fix this feature/bug in the future feature request Request for a new feature labels Oct 30, 2019
@domharrington
Copy link
Author

Hey Ben! :) thanks for the update on this, I'll be sure to follow along here for any future news. Let me know if I can help with testing anything.

Here's our cloudflare worker if you're interested: https://github.com/readmeio/cloudflare-worker. Here's the modified version of the worker to send any errors to Bugsnag: https://github.com/readmeio/cloudflare-worker/blob/144f8c2c16054d110f4e9164e3cfbfdab29ef8bf/debug-template.js#L28-L54.

Cheers!

@jamesarosen
Copy link

@bengourley the only blocker to using @bugsnag/core/client in Cloudflare is the use of navigator in @bugsnag/cuid. Cloudflare simply won't let you create a worker that references globals that don't exist. If you could remove that dependency (or just gate it on a typeof check), then the community could create a Cloudflare plugin.

@jamesarosen
Copy link

@domharrington if you add a webpack.DefinePlugin to your webpack config, you can have webpack rewrite the navigator global references:

new webpack.DefinePlugin({
  navigator: '{ userAgent: "" }',
}),

It results in some weird but completely functional code:

var mimeTypesLength = {
  userAgent: ''
}.mimeTypes ? {
  userAgent: ''
}.mimeTypes.length : 0;
var clientId = pad((mimeTypesLength + {
  userAgent: ''
}.userAgent.length).toString(36) + globalCount.toString(36), 4);

@simplenotezy
Copy link

Would be very awesome to have Cloudflare Workers support. Workers is a really amazing software, but they really lack better debugging options. Currently I am out of luck of integrating bugsnag with cloudflare workers.

@jamesarosen
Copy link

I posted a working implementation here.

@jamesarosen
Copy link

jamesarosen commented Aug 19, 2020

Cloudflare workers are always a single file. Whether you use Wrangler, Webpack, or something else to compile your files down to a single file, you're going to end up with line-number changes on every release. That makes Bugsnag's default exception group fairly useless. I find this helps a lot:

catch (e) {
  const report = createReportFromError(e, handledState)
  report.groupingHash = e.message || 'Uncaught exception'
  bugsnagClient(event).notify(report)
}

Bugsnag's sourcemap support won't work in the case of Cloudflare workers since neither the compiled JS nor the source is available at any URL.

@zorbash
Copy link

zorbash commented Jun 11, 2021

@domharrington if you add a webpack.DefinePlugin to your webpack config, you can have webpack rewrite the navigator global references:

new webpack.DefinePlugin({
  navigator: '{ userAgent: "" }',
}),

It looks like '@bugsnag/js' depends on more global properties than navigator.

new webpack.DefinePlugin({
  navigator: JSON.stringify({ userAgent: '' }),
  window: JSON.stringify({}),
  document: JSON.stringify({}),
}),

Currently getting the following error:

TypeError: Cannot read property 'host' of undefined

It'd be great to remove reliance on browser globals.

@yousif-bugsnag
Copy link
Contributor

Hi @zorbash, I'm afraid we don't have any updates on this at present. Does the working implementation posted above work for you?

@zorbash
Copy link

zorbash commented Jun 14, 2021

Hi @yousif-bugsnag, the working implementation posted above seems incomplete since the createReportFromError function is not defined anywhere.

I'm assuming the missing function is implemented as follows:

const ErrorStackParser = require('error-stack-parser')


function createReportFromError(event, error) {
  const report = new Report(e.name, e.message, ErrorStackParser.parse(e));

  report.updateMetaData('request', {
    method: event.request.method,
    url: event.request.url,
  });

  report.app = {
    id: 'name',
    version: '1.0.0',
  };

  return report;
}

Given our worker is written in TypeScript though, the application won't compile due to errors triggered by the following imports:

import Client from '@bugsnag/core/client'
import payload from '@bugsnag/core/lib/json-payload'
import { schema } from '@bugsnag/core/config'

Errors:

Could not find a declaration file for module '@bugsnag/core/client'.
Could not find a declaration file for module '@bugsnag/core/lib/json-payload'.
Could not find a declaration file for module '@bugsnag/core/config'.

TypeScript's suggestion is to install @types/bugsnag__core which doesn't exist. Any idea how to fix this?

@mattdyoung
Copy link
Contributor

I believe using the require syntax e.g.

var Client = require('@bugsnag/core/client')

should get you past the typescript issues.

I've flagged your interest in official Bugsnag support for Cloudflare workers with our product team, and we'll be sure to post back here if there are any updates.

@joshunger
Copy link

joshunger commented Aug 25, 2021

The navigator issue still exists in https://github.com/bugsnag/cuid/blob/master/lib/fingerprint.browser.js. Are you open to accepting PRs?

@abigailbramble
Copy link

@joshunger In general we're open to accepting PRs, however we'd be unlikely to accept a PR that removes navigator as we use that to help generate device IDs which is something we'd need to consider carefully if changing. Additionally there may be other areas that reference globals in @browser/js so that might not be sufficient.
You could create your own fork of the repository for now until we're able to look into adding official support for Cloudflare workers.

@joshunger
Copy link

joshunger commented Sep 6, 2021

@phillipsam Afternoon! Sounds good, thanks for letting me know. I ended up here because browser was being included in SSR when using rails webpacker. Of course multiple ways to fix but this was the easiest. For anyone else -

environment.plugins.append(
  'define',
  new DefinePlugin({
    navigator: '(typeof navigator !== \'undefined\' ? navigator : { userAgent: "" })'
  })
);

@jokedos
Copy link

jokedos commented Jun 10, 2022

Hey! Any updates on the official support for Cloudflare workers? Would be awesome to have the official package for them.

@hansottowirtz
Copy link

From the Cloudflare Workers docs:

When the global_navigator compatibility flag is set, the navigator.userAgent property is available with the value 'Cloudflare-Workers'. This can be used, for example, to reliably determine that code is running within the Workers environment.

So in your wrangler.toml, you can try adding:

compatibility_flags = ["global_navigator"]

This can at least help to patch the navigator issue. I haven't tried this solution myself though, will update when I have tried it out.

@ScottAwesome
Copy link

ScottAwesome commented Oct 25, 2022

Biggest issue here for me is next.js and bugsnag. The underlying architecture of the bugsnag plugins just don't play well, and very soon (likely announcing Oct. 25) they'll be encouraging and moving toward the cloudflare runtime underneath, however it remains to be seen if things are going to be compat / configurable.

This means Bugsnag, effectively, will have even worse compatibility with Next.js projects. Is there any way to get visibility for this? Right now I'm looking at recommending moving to a different logging platform entirely due to the limitations of the design.

Even a simple fetch based logger would be good, and would work exceedingly well in all environments.

@jclusso
Copy link

jclusso commented Jun 9, 2023

Any update on this recently?

@johnkiely1
Copy link
Member

Hi @jclusso, support for Cloudflare workers remains on our backlog. We hope to get to it soon, but at present don't have an ETA. We will post updates as soon as we have them.

@Danetag
Copy link

Danetag commented Nov 28, 2023

Hey team! Same question, any update on this? Thank you!

@clr182
Copy link

clr182 commented Dec 7, 2023

Hi @Danetag
This item is still on our backlog. Once we have more information we will be sure to update this thread.

@remorses
Copy link

remorses commented Dec 7, 2023

I will be dead before you add workers support 💀

mlbrgl added a commit to owid/owid-grapher that referenced this issue Jan 11, 2024
Add Sentry logging for /donation/* Cloudflare Pages functions routes.

At the time of writing, neither [bugsnag](bugsnag/bugsnag-js#637) nor [slack](slackapi/node-slack-sdk#1335) have official Cloudflare worker integrations.

Given the criticality of these routes, I favoured reliability and introduced a new logging app which has official Cloudflare support: https://developers.cloudflare.com/pages/functions/plugins/sentry/

We should switch to bugsnag whenever official support is available.

Testing:
- (ENV and SENTRY_DSN secrets are already defined for the preview environment in Cloudflare's "owid" project)
- temporarily disable the [Cloudflare Access rule](https://one.dash.cloudflare.com/078fcdfed9955087315dd86792e71a7e/access/apps/edit/d8c658c3-fd20-477e-ac20-e7ed7fd656de?tab=overview) by setting its  subdomain to `temp`
- send an empty JSON to https://donate.owid.pages.dev/donation/donate

-> an error is logged in sentry and an alert email is sent to [TBD]@ourworldindata.org (this will be configured when the use of Sentry is confirmed). Slack integration is only available on paid plans.
@marshallswain
Copy link

Maybe a tail worker with https://docs.bugsnag.com/api/error-reporting/ will do the trick. I haven't tried, yet.

@RayBans2111
Copy link

any updates for this?

@clr182
Copy link

clr182 commented Oct 29, 2024

Hi @RayBans2111
No update just yet. Once we have more information we will be sure to update this thread.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backlog We hope to fix this feature/bug in the future feature request Request for a new feature
Projects
None yet
Development

No branches or pull requests