sentry
sentry copied to clipboard
Sentry JS lazily-loadable loader doesn't work
Version Information
Version: 20.10.1
Description
According to the documentation (https://docs.sentry.io/platforms/javascript/install/lazy-load-sentry/#sdk-version) Sentry offers a lightweight lazy-loadable version of the Sentry JS SDK which is a lot smaller than the default bundles.
I tried to use it, but when I open the script that's shown inside the "JavaScript Loader" input box as shown in the docs, the entire contents of the script look like this:
function _sentry_noopWarning() {
console.warn("The Sentry loader you are trying to use isn't working anymore, check your configuration.");
}
var Sentry = {
addBreadcrumb: _sentry_noopWarning,
captureEvent: _sentry_noopWarning,
captureException: _sentry_noopWarning,
captureMessage: _sentry_noopWarning,
configureScope: _sentry_noopWarning,
forceLoad: _sentry_noopWarning,
init: _sentry_noopWarning,
onLoad: _sentry_noopWarning,
showReportDialog: _sentry_noopWarning,
withScope: _sentry_noopWarning,
};
_sentry_noopWarning();
I tried grep-ing through the Sentry source code about this, but I was only able to find the template that generates this script (https://github.com/getsentry/sentry/blob/master/src/sentry/templates/sentry/js-sdk-loader-noop.js.tmpl) and couldn't figure out further how does Sentry decide to show this broken version instead of the real script.
The documentation isn't helpful either.
Steps to Reproduce
Install Sentry on-premises and check the JavaScript Loader, I guess.
Logs
No logs
Hi, I think this is intended to be used by https://sentry.io or when you are using a CDN yourself. The definitions are here: https://github.com/getsentry/sentry/blob/c3da5bd066b6f30358a455b78eab4ba075c0acf9/src/sentry/conf/server.py#L1862-L1870
Can you share where you are seeing this script linked to? Maybe this is just a UI issue that we need to disable for on-premise (or when this setting is not set).
@BYK Same place it's shown in the docs, in the Client Keys (DSN) settings, when pressing "Configure" on the DSN key.

It would be great if this feature could be used on-premises as well, since there's no other way to lazily load the JS SDK
@fabis94 thanks a lot for the quick turn around! I'll be investigating this.
I can confirm that I am seeing this is the latest release of on premise as well.
Like the original poster, I followed the same path and was led to this ticket.
I’d be happy to debug or offer feedback.
I've tried a number of attempts at setting system.JS_SDK_LOADER_DEFAULT_SDK_URL in sentry/config.yml and sentry/sentry.conf.py without luck so far.
I receive various versions of "Unknown config option found:" in the logs.
I was able to get this working by setting the following in sentry/sentry.conf.py
JS_SDK_LOADER_DEFAULT_SDK_URL = "https://browser.sentry-cdn.com/%s/bundle.tracing.min.js"
May I suggest that this be set as a default in the sentry.conf.example.py?
@christopherowen Is that really lazy loading, though? It looks like it just loads the standard bundle instead of the specialized lazy-loadable version that is supposedly served by the cloud version of Sentry.
yes it is, this url is loaded by the lazy loader.
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 label it Status: Accepted, I will leave it alone ... forever!
"A weed is but an unloved flower." ― Ella Wheeler Wilcox 🥀
Any updates on this? Problem is still here in Sentry 21.4.0.dev07313f65.
@maxkachalin it is on our backlog, just didn't have time to get to it yet.
@BYK, I see, thank you very much in advance.
I've been tangled by the bot which closed issue due to inactivity.
Same here! Following @christopherowen suggestion, it worked! Thanks!
Hi all! Any workaround for this issue at this moment?
@pauloriply See https://github.com/getsentry/sentry/issues/22715#issuecomment-745151393
I was able to get this working by setting the following in sentry/sentry.conf.py
JS_SDK_LOADER_DEFAULT_SDK_URL = "https://browser.sentry-cdn.com/%s/bundle.tracing.min.js"
The downside of this approach is that the SDK is loading from a third-party CDN, which is not ideal in some cases (eg. slower load time due to having to resolve one extra hostname, you can't customize the code at all, regulatory requirements with regards to third-party servers, etc).
Until this is fixed, I'm going to try lazy loading via Webpack's lazy loading support. I've got this so far:
Edit: Code is in a Github repo now: https://github.com/Daniel15/LazySentry
// LazySentryImport.ts
// Only export the things you use, to try and keep bundle size small (tree shaking)
import {Integrations} from '@sentry/tracing';
const {BrowserTracing} = Integrations;
export {
init,
ErrorBoundary,
addBreadcrumb,
captureMessage,
captureException,
captureEvent,
configureScope,
withScope,
} from '@sentry/react';
export {BrowserTracing};
// LazySentry.ts
type SentryImportType = typeof import('./LazySentryImports');
const isDev = window.location.hostname.includes('.localdev.');
let queue: Array<(sentry: SentryImportType) => void> = [];
let errorQueue: Array<Parameters<OnErrorEventHandlerNonNull>> = [];
let rejectionQueue: Array<PromiseRejectionEvent> = [];
// Before Sentry has loaded, these functions will push calls into a queue
// After Sentry has loaded, these will be replaced with the real functions
export let addBreadcrumb: SentryImportType['addBreadcrumb'] = (...args) => {
queue.push(x => x.addBreadcrumb(...args));
};
export let captureMessage: SentryImportType['captureMessage'] = (...args) => {
queue.push(x => x.captureMessage(...args));
return '';
};
export let captureException: SentryImportType['captureException'] = (
...args
) => {
queue.push(x => x.captureException(...args));
return '';
};
export let captureEvent: SentryImportType['captureEvent'] = (...args) => {
queue.push(x => x.captureEvent(...args));
return '';
};
export let configureScope: SentryImportType['configureScope'] = (...args) =>
queue.push(x => x.configureScope(...args));
export let withScope: SentryImportType['withScope'] = (...args) =>
queue.push(x => x.withScope(...args));
export function initLazy() {
const oldOnError = window.onerror;
const oldOnUnhandledRejection = window.onunhandledrejection;
window.onerror = (...args) => errorQueue.push(args);
window.onunhandledrejection = (e: PromiseRejectionEvent) =>
rejectionQueue.push(e);
import('./LazySentryImports').then(Sentry => {
window.onerror = oldOnError;
window.onunhandledrejection = oldOnUnhandledRejection;
Sentry.init({
dsn: 'https://xxxxxxxxxx/3',
debug: isDev,
environment: isDev ? 'development' : 'production',
integrations: [new Sentry.BrowserTracing()],
tracesSampleRate: 1.0,
});
// Override the placeholder functions with the real ones
addBreadcrumb = Sentry.addBreadcrumb;
captureMessage = Sentry.captureMessage;
captureException = Sentry.captureException;
captureEvent = Sentry.captureEvent;
configureScope = Sentry.configureScope;
withScope = Sentry.withScope;
// TODO: React ErrorBoundary
// Replay queued calls and errors through Sentry's handlers
queue.forEach(call => call(Sentry));
errorQueue.forEach(x => window.onerror?.(...x));
rejectionQueue.forEach(e => window.onunhandledrejection?.(e));
});
}
Then just use the LazySentry module in your app and call initLazy somewhere (eg after page load, in a requestIdleCallback callback, etc). Basically the same as the Sentry lazy loader (https://github.com/getsentry/sentry-javascript/blob/master/packages/browser/src/loader.js) but with more modern JS, less obfuscated, TypeScript typing, and lazy loading your own built JS file rather than using the Sentry CDN.
No guarantees on the above code and I still need to finish testing it, but on an initial test it seems to work.
@Daniel15 this is not bad at all!
@Daniel15 this is not bad at all!
Thanks 😃 I started using it on https://dnstools.ws/ (https://github.com/Daniel15/dnstools/blob/9c51a38d1a86b84c9f13f940ff58108bd4468b1d/src/DnsTools.Web/ClientApp/src/index.tsx#L38) and it seems to be working fine.
I am new to Sentry. But I also ran into a similar issue when using it with Django + Vue.JS. Since in the current project it is necessary that the backend transfer the necessary configuration for the Sentry SDK in advance before returning the statics. When is a patch like this planned to be released?
Have there been any updates? Would be nice to have a working feature without workarounds
I was able to get this working by setting the following in sentry/sentry.conf.py
JS_SDK_LOADER_DEFAULT_SDK_URL = "https://browser.sentry-cdn.com/%s/bundle.tracing.min.js"May I suggest that this be set as a default in the sentry.conf.example.py?
Didn't work for me. It correctly lazily loaded the bundle when an error occurred but didn't report the issue (there was no request happening in the browser console and therefore it obviously also didn't show up in sentry).
Got it to work by loading bundle.min.js instead of bundle.tracing.min.js.
JS_SDK_LOADER_DEFAULT_SDK_URL = "https://browser.sentry-cdn.com/%s/bundle.min.js"
I was able to get this working by setting the following in sentry/sentry.conf.py
JS_SDK_LOADER_DEFAULT_SDK_URL = "https://browser.sentry-cdn.com/%s/bundle.tracing.min.js"May I suggest that this be set as a default in the sentry.conf.example.py?
Didn't work for me. It correctly lazily loaded the bundle when an error occurred but didn't report the issue (there was no request happening in the browser console and therefore it obviously also didn't show up in sentry).
Got it to work by loading bundle.min.js instead of bundle.tracing.min.js.
JS_SDK_LOADER_DEFAULT_SDK_URL = "https://browser.sentry-cdn.com/%s/bundle.min.js"
That's right
Is this still in backlog? 😢
Same problem here. CDN is not an option for me for security and performance reasons.
Yep, still on the backlog
Do you have any intention of fixing this in the near future? Asking because otherwise I need to search for another solution.
otherwise I need to search for another solution.
@MoritzGiessmann You could do something similar to what I'm doing, as a workaround: https://github.com/Daniel15/LazySentry. I'm just using Webpack's lazy loading to load the Sentry code, and keeping all errors and calls to Sentry in a queue that's flushed once Sentry finishes loading.
Do you have any intention of fixing this in the near future? Asking because otherwise I need to search for another solution.
Unfortunately not. You're welcome to try out the workaround mentioned above though and report back.
I have the same problem, on the sentry website I can open the js without problems, but on-premise it doesn't let me see the content.
Sentry.io:
On-Premise ( Self-hosted):
Thanks
I was able to get this working by setting the following in sentry/sentry.conf.py
JS_SDK_LOADER_DEFAULT_SDK_URL = "https://browser.sentry-cdn.com/%s/bundle.tracing.min.js"May I suggest that this be set as a default in the sentry.conf.example.py?
Now I am having this problem: I had problem on self-hosted with sentry script being noop functions. But fixed this by adding:
JS_SDK_LOADER_DEFAULT_SDK_URL = "https://browser.sentry-cdn.com/%s/bundle.tracing.replay.debug.min.js"
to
sentry/sentry.conf.py
using docker setup and then rerunning ./install.sh, I am on main branch.
But now I am having another issue, which is causing envelope to show 403, read on some github issues, that it is deprecated endpoint or something like that, though using latest bundle.
Any ideas anyone how to fix this? Response on sentry itself is 403 from web server. And when I using script provided by my self-hosted instance. It points to:
{{self-hosted.domain}}/api/1/envelope/?sentry_key={{project_token}}&sentry_version=7&sentry_client=sentry.javascript.browser%2F7.64.0
which responds also with 403 HTTP code. But also provides this payload:
{"detail":"event submission rejected with_reason: Cors"}
In browser response headers seem to allow all origins and all headers. Not sure where this is coming from and how to fix it.
P.S. Script request returns proper header:
curl --head https://{{self-hosted.domain}}/js-sdk-loader/{{project_token}}.min.js | grep -i access
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 2479 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
Access-Control-Allow-Origin: *
UPDATE:
Did everything without loader with script directly from CDN. By configuring everything with Sentry class/prototype. But it seems that it is not sending any requests at all. Even though integrations and specified my self-hosted instance URL. No errors are made, due to the fact, that nothing is sent and I can see it from networks tab, by filtering sentry keyword or domain: *sentry*
SOLVED: Solved by disabling Verify SSL/TLS In projects General Settings. Not sure what is happening, but seems like sentry is unable to verify some ssl certificate. I use Let's Encrypt ones. But they are set at nginx proxy and service that is being monitored. No sure what I have to configure on sentry.conf.py or conf.py so it would work with verifications.