fix(analytics) make handler loading more resilient

- Don't initialize handler's is their API key is not set
- Don't swallow exceptions when creating handlers
- Don't remove all handlers if an external one fails
- Dispose the analytics subsystem if no handlers are registered
pull/7784/head
Saúl Ibarra Corretgé 5 years ago committed by Saúl Ibarra Corretgé
parent 919be21912
commit b153bf2fb8
  1. 77
      react/features/analytics/functions.js

@ -57,12 +57,15 @@ export function resetAnalytics() {
* @param {Store} store - The redux store in which the specified {@code action} is being dispatched.
* @returns {Promise} Resolves with the handlers that have been successfully loaded.
*/
export function createHandlers({ getState }: { getState: Function }) {
export async function createHandlers({ getState }: { getState: Function }) {
getJitsiMeetGlobalNS().analyticsHandlers = [];
window.analyticsHandlers = []; // Legacy support.
if (!isAnalyticsEnabled(getState)) {
return Promise.resolve([]);
// Avoid all analytics processing if there are no handlers, since no event would be sent.
analytics.dispose();
return [];
}
const state = getState();
@ -100,43 +103,47 @@ export function createHandlers({ getState }: { getState: Function }) {
};
const handlers = [];
try {
const amplitude = new AmplitudeHandler(handlerConstructorOptions);
if (amplitudeAPPKey) {
try {
const amplitude = new AmplitudeHandler(handlerConstructorOptions);
analytics.amplitudeIdentityProps = amplitude.getIdentityProps();
analytics.amplitudeIdentityProps = amplitude.getIdentityProps();
handlers.push(amplitude);
} catch (e) {
logger.error('Failed to initialize Amplitude handler', e);
}
}
handlers.push(amplitude);
// eslint-disable-next-line no-empty
} catch (e) {}
if (matomoEndpoint && matomoSiteID) {
try {
const matomo = new MatomoHandler(handlerConstructorOptions);
try {
const matomo = new MatomoHandler(handlerConstructorOptions);
handlers.push(matomo);
// eslint-disable-next-line no-empty
} catch (e) {}
return (
_loadHandlers(scriptURLs, handlerConstructorOptions)
.then(externalHandlers => {
handlers.push(...externalHandlers);
if (handlers.length === 0) {
// Throwing an error in order to dispose the analytics in the catch clause due to the lack of any
// analytics handlers.
throw new Error('No analytics handlers created!');
}
return handlers;
})
.catch(e => {
analytics.dispose();
if (handlers.length !== 0) {
logger.error(e);
}
return [];
}));
handlers.push(matomo);
} catch (e) {
logger.error('Failed to initialize Matomo handler', e);
}
}
if (Array.isArray(scriptURLs) && scriptURLs.length > 0) {
let externalHandlers;
try {
externalHandlers = await _loadHandlers(scriptURLs, handlerConstructorOptions);
handlers.push(...externalHandlers);
} catch (e) {
logger.error('Failed to initialize external analytics handlers', e);
}
}
// Avoid all analytics processing if there are no handlers, since no event would be sent.
if (handlers.length === 0) {
analytics.dispose();
}
logger.info(`Initialized ${handlers.length} analytics handlers`);
return handlers;
}
/**

Loading…
Cancel
Save