Support config change after Sentry.init
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.
- Sentry.init is triggered on the index.html via the CDN using basic config
- Sentry config is enhanced when we get to the
main.tsstage
Another solution is to allow re-init of Sentry.
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 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.
@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.
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.
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 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 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 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 what are you doing post init (in regards to replay sampling rate), that you can't do in the init?
@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 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());
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.
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 🥀
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.
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!