sentry-javascript icon indicating copy to clipboard operation
sentry-javascript copied to clipboard

Support config change after Sentry.init

Open dcarabott opened this issue 1 year ago • 13 comments

Problem Statement

Since Sentry.init is triggered on the main.ts file for Angular, errors popping up before this file is initialised are lost. Say, a script failed for some reason and we never made it till the main.ts, that error is never reported.

One of the solutions would be to init Sentry on the index.html. This way every script error can be captured. BUT it might be the case that at the index.html stage, some configs are not yet available (Angular Environment variables for example).

Example of configs that will be applied later:

tracesSampleRate, denyUrls, beforeSend etc

Solution Brainstorm

Supporting config change after init would be of great help.

  1. Sentry.init is triggered on the index.html via the CDN using basic config
  2. Sentry config is enhanced when we get to the main.ts stage

Another solution is to allow re-init of Sentry.

dcarabott avatar Mar 05 '24 14:03 dcarabott

Hello!

The things you mentioned, can be updated by mutating the options on the client:

getClient().getOptions().tracesSampleRate = 0.5;

This is not super clean and there are some options where this may not work perfectly (e.g. when an integration needs the options at setup time), but for tracesSampleRate, denyUrls and beforeSend it should work OK!

We may want to think about a more ergonomic way to do this, though 🤔

mydea avatar Mar 07 '24 08:03 mydea

@mydea Thank you for your suggestions. This looks like it actually worked. I've assigned the following configs post init: tracesSampleRate, debug, denyUrls, beforeSend and added two integrations.

dcarabott avatar Mar 14 '24 13:03 dcarabott

@mydea I can confirm that for some reason setting the replay error sample rate as part of the replay integration config (post init), didn't work as expected. Way more replays are being recorded. Same for maskAllText etc.. Looks like the replay config is left on default.

dcarabott avatar Mar 18 '24 16:03 dcarabott

As @mydea already indicated, mutating the options after initialization can easily lead to unexpected behavior and is not suggested. You can also use a dynamic sample rate by adding a tracesSampler callback to your init. I hope this will help you at least a little bit, but unfortunately, I have to say that changing the config after init is not possible right now.

Maybe the @getsentry/replay team has a suggestion for this. Maybe also adding a sampling callback like the tracesSampler.

s1gr1d avatar Mar 19 '24 10:03 s1gr1d

It (replays) should work if don't immediately include the replay integration and instead call addIntegration() after you have set the replay sample rate.

billyvg avatar Mar 19 '24 20:03 billyvg

@billyvg Thanks for the suggestion. We're not including the replay integration on init. I'm guessing its being triggered by default on init since the CDN link includes replays as well. Can I change that default behaviour?

Or maybe I can opt out from replays on the CDN link and add Replays through the NPM one (feels messy...)

dcarabott avatar Mar 20 '24 08:03 dcarabott

@dcarabott Ah sorry, I missed that you're using CDN -- unfortunately I can't think of a clean way of doing this without accessing the internals of the integration

We currently do have some unrelated work to be able to lazy load from the CDN, which may be helpful here.

What kind of logic are you trying to do in your init in regards to the replay sample rate?

billyvg avatar Mar 20 '24 17:03 billyvg

@billyvg We're not doing much during the init process.

      Sentry.init({
                            release: '${buildInfos.sentryRelease}',
                            environment: '${
                              environment === 'local' ? 'dev' : environment
                            }',
                            maxValueLength: 4096,
                            debug: false,

                            // hardcoding values for live since Replay config won't have any effect post init
                            replaysSessionSampleRate: 0,
                            replaysOnErrorSampleRate: 0.01,
                         });

But post init we're setting some options and initialising the BrowserTracing and Replay integrations. From the looks of it the Replay integration is triggered by default as part of the init (since the CDN includes the Replay). Same for tracing. So any config changes post init won't have any effect.

dcarabott avatar Mar 21 '24 12:03 dcarabott

@dcarabott what are you doing post init (in regards to replay sampling rate), that you can't do in the init?

billyvg avatar Mar 21 '24 16:03 billyvg

@billyvg here's the integration part:

   client.addIntegration(
      new Sentry.Replay({
        maskAllText: false,
        blockAllMedia: false,
        mutationLimit: 2000,
        networkDetailAllowUrls: getNetworkDetailAllowUrls(
          SENTRY_NETWORK_DETAIL_IGNORED_URLS
        ),
        networkCaptureBodies: bootstrapEnvironment.production,
        errorSampleRate:
          bootstrapEnvironment.SENTRY_REPLAYS_ON_ERROR_SAMPLE_RATE,
      })
    );

Some of the details are not available when triggering the INIT on the index.html file. Hence why integrations are triggered later on.

dcarabott avatar Mar 21 '24 16:03 dcarabott

@dcarabott If you're using the CDN, replay integration should not be loaded until you call addIntegration(new Sentry.Replay()). It looks like you're passing errorSampleRate to the Replay constructor, which is no longer supported. In your post init, something like this should work:

  const client = window.Sentry.getClient();
  client.getOptions().replaysSessionSampleRate = 1.0;
  client.addIntegration(window.Sentry.replayIntegration());

billyvg avatar Mar 21 '24 19:03 billyvg

To add on to this, if you are using the Loader script with Replay enabled, there is no real way to do this right now. The Loader Script will automatically add the Replay integration for you if Replay is enabled, which will take the options at the time of init.

If this is what you need, you'll probably need to switch to using the CDN manually and do - see https://docs.sentry.io/platforms/javascript/install/loader/#cdn. Then you can load the bundle including replay at the start of the page, manually call Sentry.init() without adding Replay, and use addIntegration(new Replay(...)) when you're ready to do so.

mydea avatar Mar 25 '24 08:03 mydea

This issue has gone three weeks without activity. In another week, I will close it.

But! If you comment or otherwise update it, I will reset the clock, and if you remove the label Waiting for: Community, I will leave it alone ... forever!


"A weed is but an unloved flower." ― Ella Wheeler Wilcox 🥀

getsantry[bot] avatar May 16 '24 07:05 getsantry[bot]

I have similar issue in our nuxt app, which initializes sentry in plugins, but errors that happen before the hydration are missing. One idea was to initialize sentry in index.html head, but we need to pass some arguments like mentioned above, and they are not available when initializing in the head. For example app argument is the vue app instance which we do not have access to, therefore would be great to be able to initialize it in head and then extend it or reinitialize it.

gloompiq avatar Jun 26 '24 14:06 gloompiq

We are currently working on a fully integrated nuxt SDK - see https://github.com/getsentry/sentry-javascript/issues/9095. That may handle these things better out of the box!

mydea avatar Jun 26 '24 14:06 mydea