@rudderstack/analytics-js 3.7.6 → 3.7.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/dist/npm/legacy/bundled/cjs/index.cjs +29 -47
- package/dist/npm/legacy/bundled/esm/index.mjs +29 -47
- package/dist/npm/legacy/bundled/umd/index.js +29 -47
- package/dist/npm/legacy/cjs/index.cjs +29 -47
- package/dist/npm/legacy/content-script/cjs/index.cjs +29 -47
- package/dist/npm/legacy/content-script/esm/index.mjs +29 -47
- package/dist/npm/legacy/content-script/umd/index.js +29 -47
- package/dist/npm/legacy/esm/index.mjs +29 -47
- package/dist/npm/legacy/umd/index.js +29 -47
- package/dist/npm/modern/bundled/cjs/index.cjs +29 -47
- package/dist/npm/modern/bundled/esm/index.mjs +29 -47
- package/dist/npm/modern/bundled/umd/index.js +29 -47
- package/dist/npm/modern/cjs/index.cjs +15 -32
- package/dist/npm/modern/content-script/cjs/index.cjs +29 -47
- package/dist/npm/modern/content-script/esm/index.mjs +29 -47
- package/dist/npm/modern/content-script/umd/index.js +29 -47
- package/dist/npm/modern/esm/index.mjs +15 -32
- package/dist/npm/modern/umd/index.js +15 -32
- package/package.json +1 -1
@@ -370,7 +370,7 @@ payload.groupId=tryStringify(payload.groupId);if(isObjectLiteralAndNotNull(paylo
|
|
370
370
|
|
371
371
|
const CAPABILITIES_MANAGER='CapabilitiesManager';const CONFIG_MANAGER='ConfigManager';const EVENT_MANAGER='EventManager';const PLUGINS_MANAGER='PluginsManager';const USER_SESSION_MANAGER='UserSessionManager';const ERROR_HANDLER='ErrorHandler';const PLUGIN_ENGINE='PluginEngine';const STORE_MANAGER='StoreManager';const READY_API='readyApi';const EVENT_REPOSITORY='EventRepository';const EXTERNAL_SRC_LOADER='ExternalSrcLoader';const HTTP_CLIENT='HttpClient';const RS_APP='RudderStackApplication';const ANALYTICS_CORE='AnalyticsCore';
|
372
372
|
|
373
|
-
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.7.
|
373
|
+
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.7.8';const APP_NAMESPACE='com.rudderlabs.javascript';const MODULE_TYPE='npm';const ADBLOCK_PAGE_CATEGORY='RudderJS-Initiated';const ADBLOCK_PAGE_NAME='ad-block page request';const ADBLOCK_PAGE_PATH='/ad-blocked';const GLOBAL_PRELOAD_BUFFER='preloadedEventsBuffer';const CONSENT_TRACK_EVENT_NAME='Consent Management Interaction';
|
374
374
|
|
375
375
|
const QUERY_PARAM_TRAIT_PREFIX='ajs_trait_';const QUERY_PARAM_PROPERTY_PREFIX='ajs_prop_';const QUERY_PARAM_ANONYMOUS_ID_KEY='ajs_aid';const QUERY_PARAM_USER_ID_KEY='ajs_uid';const QUERY_PARAM_TRACK_EVENT_NAME_KEY='ajs_event';
|
376
376
|
|
@@ -575,35 +575,14 @@ processRawPlugins(callback){callback(this.plugins);this.cache={};}invoke(extPoin
|
|
575
575
|
extensionPointName=extensionPointName.replace(/(^!|!$)/g,'');if(!extensionPointName){throw new Error(PLUGIN_EXT_POINT_INVALID_ERROR);}const extensionPointNameParts=extensionPointName.split('.');extensionPointNameParts.pop();const pluginMethodPath=extensionPointNameParts.join('.');const pluginsToInvoke=allowMultiple?this.getPlugins(extensionPointName):[this.getPlugins(extensionPointName)[0]];return pluginsToInvoke.map(plugin=>{const method=getValueByPath(plugin,extensionPointName);if(!isFunction(method)||noCall){return method;}try{return method.apply(getValueByPath(plugin,pluginMethodPath),args);}catch(err){// When a plugin failed, doesn't break the app
|
576
576
|
if(throws){throw err;}else {this.logger?.error(PLUGIN_INVOCATION_ERROR(PLUGIN_ENGINE,extensionPointName,plugin.name),err);}}return null;});}invokeSingle(extPoint,...args){return this.invoke(extPoint,false,...args)[0];}invokeMultiple(extPoint,...args){return this.invoke(extPoint,true,...args);}}const defaultPluginEngine=new PluginEngine({throws:true},defaultLogger);
|
577
577
|
|
578
|
-
const
|
578
|
+
const LOAD_ORIGIN='RS_JS_SDK';
|
579
579
|
|
580
580
|
/**
|
581
581
|
* Utility method to normalise errors
|
582
582
|
*/const processError=error=>{let errorMessage;try{if(isString(error)){errorMessage=error;}else if(error instanceof Error){errorMessage=error.message;}else if(error instanceof ErrorEvent){errorMessage=error.message;}else {errorMessage=error.message?error.message:stringifyWithoutCircular(error);}}catch(e){errorMessage=`Unknown error: ${e.message}`;}return errorMessage;};const getNormalizedErrorForUnhandledError=error=>{try{if(error instanceof Error||error instanceof ErrorEvent||error instanceof PromiseRejectionEvent&&error.reason){return error;}// TODO: remove this block once all device mode integrations start using the v3 script loader module (TS)
|
583
|
-
|
584
|
-
//
|
585
|
-
|
586
|
-
// if (eventTarget && eventTarget.localName !== 'script') {
|
587
|
-
// return undefined;
|
588
|
-
// }
|
589
|
-
// // Discard script errors that are not originated at SDK or from native SDKs
|
590
|
-
// if (
|
591
|
-
// eventTarget?.dataset &&
|
592
|
-
// (eventTarget.dataset.loader !== LOAD_ORIGIN ||
|
593
|
-
// eventTarget.dataset.isnonnativesdk !== 'true')
|
594
|
-
// ) {
|
595
|
-
// return undefined;
|
596
|
-
// }
|
597
|
-
// const errorMessage = `Error in loading a third-party script from URL ${eventTarget?.src} with ID ${eventTarget?.id}.`;
|
598
|
-
// return Object.create(error, {
|
599
|
-
// message: { value: errorMessage },
|
600
|
-
// });
|
601
|
-
// }
|
602
|
-
return undefined;}catch(e){return e;}};/**
|
603
|
-
* A function to determine whether the error should be promoted to notify or not
|
604
|
-
* @param {Error} error
|
605
|
-
* @returns
|
606
|
-
*/const isAllowedToBeNotified=error=>{if((error instanceof Error||error instanceof ErrorEvent)&&error.message){return !ERROR_MESSAGES_TO_BE_FILTERED.some(e=>error.message.includes(e));}if(error instanceof PromiseRejectionEvent&&typeof error.reason==='string'){return !ERROR_MESSAGES_TO_BE_FILTERED.some(e=>error.reason.includes(e));}return true;};
|
583
|
+
if(error instanceof Event){const eventTarget=error.target;// Discard all the non-script loading errors
|
584
|
+
if(eventTarget&&eventTarget.localName!=='script'){return undefined;}// Discard script errors that are not originated at SDK or from native SDKs
|
585
|
+
if(eventTarget?.dataset&&(eventTarget.dataset.loader!==LOAD_ORIGIN||eventTarget.dataset.isnonnativesdk!=='true')){return undefined;}const errorMessage=`Error in loading a third-party script from URL ${eventTarget?.src} with ID ${eventTarget?.id}.`;return Object.create(error,{message:{value:errorMessage}});}return error;}catch(e){return e;}};
|
607
586
|
|
608
587
|
/**
|
609
588
|
* A service to handle errors
|
@@ -624,7 +603,7 @@ breadcrumb,this.logger,state);}catch(err){this.onError(err,ERROR_HANDLER,'errorR
|
|
624
603
|
* Send handled errors to external error monitoring service via a plugin
|
625
604
|
*
|
626
605
|
* @param {Error} error Error instance from handled error
|
627
|
-
*/notifyError(error,errorState){if(this.pluginEngine&&this.httpClient
|
606
|
+
*/notifyError(error,errorState){if(this.pluginEngine&&this.httpClient){try{this.pluginEngine.invokeSingle('errorReporting.notify',this.pluginEngine,// deprecated parameter
|
628
607
|
this.errReportingClient,// deprecated parameter
|
629
608
|
error,state,this.logger,this.httpClient,errorState);}catch(err){// Not calling onError here as we don't want to go into infinite loop
|
630
609
|
this.logger?.error(NOTIFY_FAILURE_ERROR(ERROR_HANDLER),err);}}}}const defaultErrorHandler=new ErrorHandler(defaultLogger,defaultPluginEngine);
|
@@ -1105,6 +1084,8 @@ const queueErrResp=isErrRetryable(details)?details:null;if(!queueErrResp||attemp
|
|
1105
1084
|
|
1106
1085
|
const METRICS_PAYLOAD_VERSION='1';
|
1107
1086
|
|
1087
|
+
const FAILED_REQUEST_ERR_MSG_PREFIX='The request failed';const ERROR_MESSAGES_TO_BE_FILTERED=[FAILED_REQUEST_ERR_MSG_PREFIX];
|
1088
|
+
|
1108
1089
|
// Errors from the below scripts are NOT allowed to reach Bugsnag
|
1109
1090
|
const SDK_FILE_NAME_PREFIXES=()=>['rsa'// Prefix for all the SDK scripts including plugins and module federated chunks
|
1110
1091
|
];const DEV_HOSTS=['www.test-host.com','localhost','127.0.0.1','[::1]'];// List of keys to exclude from the metadata
|
@@ -1112,11 +1093,19 @@ const SDK_FILE_NAME_PREFIXES=()=>['rsa'// Prefix for all the SDK scripts includi
|
|
1112
1093
|
const APP_STATE_EXCLUDE_KEYS=['userId','userTraits','groupId','groupTraits','anonymousId','config','instance',// destination instance objects
|
1113
1094
|
'eventBuffer',// pre-load event buffer (may contain PII)
|
1114
1095
|
'traits'];const REQUEST_TIMEOUT_MS$1=10*1000;// 10 seconds
|
1115
|
-
const NOTIFIER_NAME='RudderStack JavaScript SDK Error Notifier';const SDK_GITHUB_URL='https://github.com/rudderlabs/rudder-sdk-js';const SOURCE_NAME='js';
|
1096
|
+
const NOTIFIER_NAME='RudderStack JavaScript SDK Error Notifier';const SDK_GITHUB_URL='https://github.com/rudderlabs/rudder-sdk-js';const SOURCE_NAME='js';const ERROR_REPORTING_PLUGIN='ErrorReportingPlugin';
|
1116
1097
|
|
1117
1098
|
const getConfigForPayloadCreation=(err,errorType)=>{switch(errorType){case ErrorType.UNHANDLEDEXCEPTION:{const{error}=err;return {component:'unhandledException handler',tolerateNonErrors:true,errorFramesToSkip:1,normalizedError:error||err};}case ErrorType.UNHANDLEDREJECTION:{const error=err;return {component:'unhandledrejection handler',tolerateNonErrors:false,errorFramesToSkip:1,normalizedError:error.reason};}case ErrorType.HANDLEDEXCEPTION:default:return {component:'notify()',tolerateNonErrors:true,errorFramesToSkip:2,normalizedError:err};}};const createNewBreadcrumb=(message,metaData)=>({type:'manual',name:message,timestamp:new Date(),metaData:metaData??{}});const getReleaseStage=()=>{const host=globalThis.location.hostname;return host&&DEV_HOSTS.includes(host)?'development':'production';};const getAppStateForMetadata=state=>{const stateStr=stringifyWithoutCircular(state,false,APP_STATE_EXCLUDE_KEYS);return stateStr!==null?JSON.parse(stateStr):{};};const getURLWithoutQueryString=()=>{const url=globalThis.location.href.split('?');return url[0];};const getErrorContext=event=>{const{message}=event;let context=message;// Hack for easily grouping the script load errors
|
1118
1099
|
// on the dashboard
|
1119
|
-
if(message.includes('Error in loading a third-party script')){context='Script load failures';}return context;};const getBugsnagErrorEvent=(payload,errorState,state)=>({notifier:{name:NOTIFIER_NAME,version:state.context.app.value.version,url:SDK_GITHUB_URL},events:[{payloadVersion:'5',exceptions:clone(payload.errors),severity:errorState.severity,unhandled:errorState.unhandled,severityReason:errorState.severityReason,app:{version:state.context.app.value.version,releaseStage:getReleaseStage()},device:{locale:state.context.locale.value??undefined,userAgent:state.context.userAgent.value??undefined,time:new Date()},request:{url:getURLWithoutQueryString(),clientIp:'[NOT COLLECTED]'},breadcrumbs:clone(state.reporting.breadcrumbs.value),context:getErrorContext(payload.errors[0]),metaData:{sdk:{name:'JS',installType:state.context.app.value.installType},state:getAppStateForMetadata(state)??{},source:{snippetVersion:globalThis.RudderSnippetVersion}},user:{id:state.source.value?.id??state.lifecycle.writeKey.value}}]})
|
1100
|
+
if(message.includes('Error in loading a third-party script')){context='Script load failures';}return context;};const getBugsnagErrorEvent=(payload,errorState,state)=>({notifier:{name:NOTIFIER_NAME,version:state.context.app.value.version,url:SDK_GITHUB_URL},events:[{payloadVersion:'5',exceptions:clone(payload.errors),severity:errorState.severity,unhandled:errorState.unhandled,severityReason:errorState.severityReason,app:{version:state.context.app.value.version,releaseStage:getReleaseStage()},device:{locale:state.context.locale.value??undefined,userAgent:state.context.userAgent.value??undefined,time:new Date()},request:{url:getURLWithoutQueryString(),clientIp:'[NOT COLLECTED]'},breadcrumbs:clone(state.reporting.breadcrumbs.value),context:getErrorContext(payload.errors[0]),metaData:{sdk:{name:'JS',installType:state.context.app.value.installType},state:getAppStateForMetadata(state)??{},source:{snippetVersion:globalThis.RudderSnippetVersion}},user:{id:state.source.value?.id??state.lifecycle.writeKey.value}}]});/**
|
1101
|
+
* A function to determine whether the error should be promoted to notify or not
|
1102
|
+
* @param {Error} error
|
1103
|
+
* @returns
|
1104
|
+
*/const isAllowedToBeNotified=event=>{const errorMessage=event.message;if(errorMessage&&typeof errorMessage==='string'){return !ERROR_MESSAGES_TO_BE_FILTERED.some(e=>errorMessage.includes(e));}return true;};/**
|
1105
|
+
* A function to determine if the error is from Rudder SDK
|
1106
|
+
* @param {Error} event
|
1107
|
+
* @returns
|
1108
|
+
*/const isRudderSDKError=event=>{const errorOrigin=event.stacktrace?.[0]?.file;if(!errorOrigin||typeof errorOrigin!=='string'){return false;}const srcFileName=errorOrigin.substring(errorOrigin.lastIndexOf('/')+1);const paths=errorOrigin.split('/');// extract the parent folder name from the error origin file path
|
1120
1109
|
// Ex: parentFolderName will be 'sample' for url: https://example.com/sample/file.min.js
|
1121
1110
|
const parentFolderName=paths[paths.length-2];return parentFolderName===CDN_INT_DIR||SDK_FILE_NAME_PREFIXES().some(prefix=>srcFileName.startsWith(prefix)&&srcFileName.endsWith('.js'));};const getErrorDeliveryPayload=(payload,state)=>{const data={version:METRICS_PAYLOAD_VERSION,message_id:generateUUID(),source:{name:SOURCE_NAME,sdk_version:state.context.app.value.version,write_key:state.lifecycle.writeKey.value,install_type:state.context.app.value.installType},errors:payload};return stringifyWithoutCircular(data);};
|
1122
1111
|
|
@@ -1160,19 +1149,10 @@ const formatStackframe=frame=>{const f={file:frame.fileName,method:normaliseFunc
|
|
1160
1149
|
// This adds one.
|
1161
1150
|
if(f.lineNumber>-1&&!f.file&&!f.method){f.file='global code';}return f;};const ensureString=str=>typeof str==='string'?str:'';function createBugsnagError(errorClass,errorMessage,stacktrace){return {errorClass:ensureString(errorClass),message:ensureString(errorMessage),type:'browserjs',stacktrace:stacktrace.reduce((accum,frame)=>{const f=formatStackframe(frame);// don't include a stackframe if none of its properties are defined
|
1162
1151
|
try{if(JSON.stringify(f)==='{}')return accum;return accum.concat(f);}catch(e){return accum;}},[])};}// Helpers
|
1163
|
-
const getStacktrace=(error,errorFramesToSkip)=>{if(hasStack(error))return ErrorStackParser.parse(error).slice(errorFramesToSkip);return [];};const hasNecessaryFields=error=>(typeof error.name==='string'||typeof error.errorClass==='string')&&(typeof error.message==='string'||typeof error.errorMessage==='string');const normaliseError=(maybeError,
|
1164
|
-
//
|
1165
|
-
// - the promise rejection handler (both in the browser and node)
|
1166
|
-
// - the node uncaughtException handler
|
1167
|
-
//
|
1168
|
-
// We are really limited in what we can do to get a stacktrace. So we use the
|
1169
|
-
// tolerateNonErrors option to ensure that the resulting error communicates as
|
1170
|
-
// such.
|
1171
|
-
if(!tolerateNonErrors){if(isError(maybeError)){error=maybeError;}else {error=createAndLogInputError(typeof maybeError);internalFrames+=2;}}else {switch(typeof maybeError){case'string':case'number':case'boolean':error=new Error(String(maybeError));internalFrames+=1;break;case'function':error=createAndLogInputError('function');internalFrames+=2;break;case'object':if(maybeError!==null&&isError(maybeError)){error=maybeError;}else if(maybeError!==null&&hasNecessaryFields(maybeError)){error=new Error(maybeError.message||maybeError.errorMessage);error.name=maybeError.name||maybeError.errorClass;internalFrames+=1;}else {error=createAndLogInputError(maybeError===null?'null':'unsupported object');internalFrames+=2;}break;default:error=createAndLogInputError('nothing');internalFrames+=2;}}if(!hasStack(error)){// in IE10/11 a new Error() doesn't have a stacktrace until you throw it, so try that here
|
1152
|
+
const getStacktrace=(error,errorFramesToSkip)=>{if(hasStack(error))return ErrorStackParser.parse(error).slice(errorFramesToSkip);return [];};const hasNecessaryFields=error=>(typeof error.name==='string'||typeof error.errorClass==='string')&&(typeof error.message==='string'||typeof error.errorMessage==='string');const normaliseError=(maybeError,component,logger)=>{let error;let internalFrames=0;if(isError(maybeError)){error=maybeError;}else if(typeof maybeError==='object'&&hasNecessaryFields(maybeError)){error=new Error(maybeError.message||maybeError.errorMessage);error.name=maybeError.name||maybeError.errorClass;internalFrames+=1;}else {logger?.warn(`${ERROR_REPORTING_PLUGIN}:: ${component} received a non-error: ${stringifyWithoutCircular(error)}`);error=undefined;}if(error&&!hasStack(error)){// in IE10/11 a new Error() doesn't have a stacktrace until you throw it, so try that here
|
1172
1153
|
try{throw error;}catch(e){if(hasStack(e)){error=e;// if the error only got a stacktrace after we threw it here, we know it
|
1173
|
-
// will only have one extra internal frame from this function
|
1174
|
-
|
1175
|
-
internalFrames=1;}}}return [error,internalFrames];};class ErrorFormat{constructor(errorClass,errorMessage,stacktrace){this.errors=[createBugsnagError(errorClass,errorMessage,stacktrace)];}static create(maybeError,tolerateNonErrors,handledState,component,errorFramesToSkip=0,logger){const[error,internalFrames]=normaliseError(maybeError,tolerateNonErrors,component,logger);let event;try{const stacktrace=getStacktrace(error,// if an error was created/throw in the normaliseError() function, we need to
|
1154
|
+
// will only have one extra internal frame from this function
|
1155
|
+
internalFrames=1;}}}return [error,internalFrames];};class ErrorFormat{constructor(errorClass,errorMessage,stacktrace){this.errors=[createBugsnagError(errorClass,errorMessage,stacktrace)];}static create(maybeError,tolerateNonErrors,handledState,component,errorFramesToSkip=0,logger){const[error,internalFrames]=normaliseError(maybeError,component,logger);if(!error){return undefined;}let event;try{const stacktrace=getStacktrace(error,// if an error was created/throw in the normaliseError() function, we need to
|
1176
1156
|
// tell the getStacktrace() function to skip the number of frames we know will
|
1177
1157
|
// be from our own functions. This is added to the number of frames deep we
|
1178
1158
|
// were told about
|
@@ -1183,7 +1163,7 @@ const INVALID_SOURCE_CONFIG_ERROR=`Invalid source configuration or source id.`;
|
|
1183
1163
|
const pluginName$9='ErrorReporting';const ErrorReporting=()=>({name:pluginName$9,deps:[],initialize:state=>{state.plugins.loadedPlugins.value=[...state.plugins.loadedPlugins.value,pluginName$9];state.reporting.isErrorReportingPluginLoaded.value=true;if(state.reporting.breadcrumbs?.value){state.reporting.breadcrumbs.value=[createNewBreadcrumb('Error Reporting Plugin Loaded')];}},errorReporting:{// This extension point is deprecated
|
1184
1164
|
// TODO: Remove this in the next major release
|
1185
1165
|
init:(state,pluginEngine,externalSrcLoader,logger,isInvokedFromLatestCore)=>{if(isInvokedFromLatestCore){return undefined;}if(!state.source.value?.config||!state.source.value?.id){return Promise.reject(new Error(INVALID_SOURCE_CONFIG_ERROR));}return pluginEngine.invokeSingle('errorReportingProvider.init',state,externalSrcLoader,logger);},notify:(pluginEngine,client,error,state,logger,httpClient,errorState)=>{if(httpClient){const{component,tolerateNonErrors,errorFramesToSkip,normalizedError}=getConfigForPayloadCreation(error,errorState?.severityReason.type);// Generate the error payload
|
1186
|
-
const errorPayload=ErrorFormat.create(normalizedError,tolerateNonErrors,errorState,component,errorFramesToSkip,logger)
|
1166
|
+
const errorPayload=ErrorFormat.create(normalizedError,tolerateNonErrors,errorState,component,errorFramesToSkip,logger);if(!errorPayload||!isAllowedToBeNotified(errorPayload.errors[0])){return;}// filter errors
|
1187
1167
|
if(!isRudderSDKError(errorPayload.errors[0])){return;}// enrich error payload
|
1188
1168
|
const bugsnagPayload=getBugsnagErrorEvent(errorPayload,errorState,state);// send it to metrics service
|
1189
1169
|
httpClient?.getAsyncData({url:state.metrics.metricsServiceUrl.value,options:{method:'POST',data:getErrorDeliveryPayload(bugsnagPayload,state),sendRawData:true},isRawResponse:true,timeout:REQUEST_TIMEOUT_MS$1,callback:(result,details)=>{// do nothing
|
@@ -2702,9 +2682,14 @@ if(utmParam==='campaign'){utmParam='name';}result[utmParam]=value;}});}catch(err
|
|
2702
2682
|
*/const getUrlWithoutHash=url=>{let urlWithoutHash=url;try{const urlObj=new URL(url);urlWithoutHash=urlObj.origin+urlObj.pathname+urlObj.search;}catch(error){// Do nothing
|
2703
2683
|
}return urlWithoutHash;};
|
2704
2684
|
|
2685
|
+
/**
|
2686
|
+
* Determines if the SDK is running inside a chrome extension
|
2687
|
+
* @returns boolean
|
2688
|
+
*/const isSDKRunningInChromeExtension=()=>!!(window.chrome&&window.chrome.runtime&&window.chrome.runtime.id);
|
2689
|
+
|
2705
2690
|
const DEFAULT_PRE_CONSENT_STORAGE_STRATEGY='none';const DEFAULT_PRE_CONSENT_EVENTS_DELIVERY_TYPE='immediate';
|
2706
2691
|
|
2707
|
-
const isMetricsReportingEnabled=sourceConfig=>sourceConfig?.statsCollection?.metrics?.enabled===true;
|
2692
|
+
const isErrorReportingEnabled=sourceConfig=>sourceConfig?.statsCollection?.errors?.enabled===true;const isMetricsReportingEnabled=sourceConfig=>sourceConfig?.statsCollection?.metrics?.enabled===true;
|
2708
2693
|
|
2709
2694
|
/**
|
2710
2695
|
* Validates and normalizes the consent options provided by the user
|
@@ -2738,10 +2723,7 @@ for(const script of scripts){const src=script.getAttribute('src');if(src&&sdkFil
|
|
2738
2723
|
* Updates the reporting state variables from the source config data
|
2739
2724
|
* @param res Source config
|
2740
2725
|
* @param logger Logger instance
|
2741
|
-
*/const updateReportingState=res=>{state.reporting.isErrorReportingEnabled.value=
|
2742
|
-
// state.reporting.isErrorReportingEnabled.value =
|
2743
|
-
// isErrorReportingEnabled(res.source.config) && !isSDKRunningInChromeExtension();
|
2744
|
-
state.reporting.isMetricsReportingEnabled.value=isMetricsReportingEnabled(res.source.config);};const updateStorageStateFromLoadOptions=logger=>{const{useServerSideCookies,dataServiceEndpoint,storage:storageOptsFromLoad,setCookieDomain,sameDomainCookiesOnly}=state.loadOptions.value;let storageType=storageOptsFromLoad?.type;if(isDefined(storageType)&&!isValidStorageType(storageType)){logger?.warn(STORAGE_TYPE_VALIDATION_WARNING(CONFIG_MANAGER,storageType,DEFAULT_STORAGE_TYPE));storageType=DEFAULT_STORAGE_TYPE;}let storageEncryptionVersion=storageOptsFromLoad?.encryption?.version;const encryptionPluginName=storageEncryptionVersion&&StorageEncryptionVersionsToPluginNameMap[storageEncryptionVersion];if(!isUndefined(storageEncryptionVersion)&&isUndefined(encryptionPluginName)){// set the default encryption plugin
|
2726
|
+
*/const updateReportingState=res=>{state.reporting.isErrorReportingEnabled.value=isErrorReportingEnabled(res.source.config)&&!isSDKRunningInChromeExtension();state.reporting.isMetricsReportingEnabled.value=isMetricsReportingEnabled(res.source.config);};const updateStorageStateFromLoadOptions=logger=>{const{useServerSideCookies,dataServiceEndpoint,storage:storageOptsFromLoad,setCookieDomain,sameDomainCookiesOnly}=state.loadOptions.value;let storageType=storageOptsFromLoad?.type;if(isDefined(storageType)&&!isValidStorageType(storageType)){logger?.warn(STORAGE_TYPE_VALIDATION_WARNING(CONFIG_MANAGER,storageType,DEFAULT_STORAGE_TYPE));storageType=DEFAULT_STORAGE_TYPE;}let storageEncryptionVersion=storageOptsFromLoad?.encryption?.version;const encryptionPluginName=storageEncryptionVersion&&StorageEncryptionVersionsToPluginNameMap[storageEncryptionVersion];if(!isUndefined(storageEncryptionVersion)&&isUndefined(encryptionPluginName)){// set the default encryption plugin
|
2745
2727
|
logger?.warn(UNSUPPORTED_STORAGE_ENCRYPTION_VERSION_WARNING(CONFIG_MANAGER,storageEncryptionVersion,StorageEncryptionVersionsToPluginNameMap,DEFAULT_STORAGE_ENCRYPTION_VERSION));storageEncryptionVersion=DEFAULT_STORAGE_ENCRYPTION_VERSION;}else if(isUndefined(storageEncryptionVersion)){storageEncryptionVersion=DEFAULT_STORAGE_ENCRYPTION_VERSION;}// Allow migration only if the configured encryption version is the default encryption version
|
2746
2728
|
const configuredMigrationValue=storageOptsFromLoad?.migrate;const finalMigrationVal=configuredMigrationValue&&storageEncryptionVersion===DEFAULT_STORAGE_ENCRYPTION_VERSION;if(configuredMigrationValue===true&&finalMigrationVal!==configuredMigrationValue){logger?.warn(STORAGE_DATA_MIGRATION_OVERRIDE_WARNING(CONFIG_MANAGER,storageEncryptionVersion,DEFAULT_STORAGE_ENCRYPTION_VERSION));}r(()=>{state.storage.type.value=storageType;let cookieOptions=storageOptsFromLoad?.cookie??{};if(useServerSideCookies){state.serverCookies.isEnabledServerSideCookies.value=useServerSideCookies;const providedCookieDomain=cookieOptions.domain??setCookieDomain;/**
|
2747
2729
|
* Based on the following conditions, we decide whether to use the exact domain or not to determine the data service URL:
|
@@ -376,7 +376,7 @@
|
|
376
376
|
|
377
377
|
const CAPABILITIES_MANAGER='CapabilitiesManager';const CONFIG_MANAGER='ConfigManager';const EVENT_MANAGER='EventManager';const PLUGINS_MANAGER='PluginsManager';const USER_SESSION_MANAGER='UserSessionManager';const ERROR_HANDLER='ErrorHandler';const PLUGIN_ENGINE='PluginEngine';const STORE_MANAGER='StoreManager';const READY_API='readyApi';const EVENT_REPOSITORY='EventRepository';const EXTERNAL_SRC_LOADER='ExternalSrcLoader';const HTTP_CLIENT='HttpClient';const RS_APP='RudderStackApplication';const ANALYTICS_CORE='AnalyticsCore';
|
378
378
|
|
379
|
-
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.7.
|
379
|
+
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.7.8';const APP_NAMESPACE='com.rudderlabs.javascript';const MODULE_TYPE='npm';const ADBLOCK_PAGE_CATEGORY='RudderJS-Initiated';const ADBLOCK_PAGE_NAME='ad-block page request';const ADBLOCK_PAGE_PATH='/ad-blocked';const GLOBAL_PRELOAD_BUFFER='preloadedEventsBuffer';const CONSENT_TRACK_EVENT_NAME='Consent Management Interaction';
|
380
380
|
|
381
381
|
const QUERY_PARAM_TRAIT_PREFIX='ajs_trait_';const QUERY_PARAM_PROPERTY_PREFIX='ajs_prop_';const QUERY_PARAM_ANONYMOUS_ID_KEY='ajs_aid';const QUERY_PARAM_USER_ID_KEY='ajs_uid';const QUERY_PARAM_TRACK_EVENT_NAME_KEY='ajs_event';
|
382
382
|
|
@@ -581,35 +581,14 @@
|
|
581
581
|
extensionPointName=extensionPointName.replace(/(^!|!$)/g,'');if(!extensionPointName){throw new Error(PLUGIN_EXT_POINT_INVALID_ERROR);}const extensionPointNameParts=extensionPointName.split('.');extensionPointNameParts.pop();const pluginMethodPath=extensionPointNameParts.join('.');const pluginsToInvoke=allowMultiple?this.getPlugins(extensionPointName):[this.getPlugins(extensionPointName)[0]];return pluginsToInvoke.map(plugin=>{const method=getValueByPath(plugin,extensionPointName);if(!isFunction(method)||noCall){return method;}try{return method.apply(getValueByPath(plugin,pluginMethodPath),args);}catch(err){// When a plugin failed, doesn't break the app
|
582
582
|
if(throws){throw err;}else {this.logger?.error(PLUGIN_INVOCATION_ERROR(PLUGIN_ENGINE,extensionPointName,plugin.name),err);}}return null;});}invokeSingle(extPoint,...args){return this.invoke(extPoint,false,...args)[0];}invokeMultiple(extPoint,...args){return this.invoke(extPoint,true,...args);}}const defaultPluginEngine=new PluginEngine({throws:true},defaultLogger);
|
583
583
|
|
584
|
-
const
|
584
|
+
const LOAD_ORIGIN='RS_JS_SDK';
|
585
585
|
|
586
586
|
/**
|
587
587
|
* Utility method to normalise errors
|
588
588
|
*/const processError=error=>{let errorMessage;try{if(isString(error)){errorMessage=error;}else if(error instanceof Error){errorMessage=error.message;}else if(error instanceof ErrorEvent){errorMessage=error.message;}else {errorMessage=error.message?error.message:stringifyWithoutCircular(error);}}catch(e){errorMessage=`Unknown error: ${e.message}`;}return errorMessage;};const getNormalizedErrorForUnhandledError=error=>{try{if(error instanceof Error||error instanceof ErrorEvent||error instanceof PromiseRejectionEvent&&error.reason){return error;}// TODO: remove this block once all device mode integrations start using the v3 script loader module (TS)
|
589
|
-
|
590
|
-
//
|
591
|
-
|
592
|
-
// if (eventTarget && eventTarget.localName !== 'script') {
|
593
|
-
// return undefined;
|
594
|
-
// }
|
595
|
-
// // Discard script errors that are not originated at SDK or from native SDKs
|
596
|
-
// if (
|
597
|
-
// eventTarget?.dataset &&
|
598
|
-
// (eventTarget.dataset.loader !== LOAD_ORIGIN ||
|
599
|
-
// eventTarget.dataset.isnonnativesdk !== 'true')
|
600
|
-
// ) {
|
601
|
-
// return undefined;
|
602
|
-
// }
|
603
|
-
// const errorMessage = `Error in loading a third-party script from URL ${eventTarget?.src} with ID ${eventTarget?.id}.`;
|
604
|
-
// return Object.create(error, {
|
605
|
-
// message: { value: errorMessage },
|
606
|
-
// });
|
607
|
-
// }
|
608
|
-
return undefined;}catch(e){return e;}};/**
|
609
|
-
* A function to determine whether the error should be promoted to notify or not
|
610
|
-
* @param {Error} error
|
611
|
-
* @returns
|
612
|
-
*/const isAllowedToBeNotified=error=>{if((error instanceof Error||error instanceof ErrorEvent)&&error.message){return !ERROR_MESSAGES_TO_BE_FILTERED.some(e=>error.message.includes(e));}if(error instanceof PromiseRejectionEvent&&typeof error.reason==='string'){return !ERROR_MESSAGES_TO_BE_FILTERED.some(e=>error.reason.includes(e));}return true;};
|
589
|
+
if(error instanceof Event){const eventTarget=error.target;// Discard all the non-script loading errors
|
590
|
+
if(eventTarget&&eventTarget.localName!=='script'){return undefined;}// Discard script errors that are not originated at SDK or from native SDKs
|
591
|
+
if(eventTarget?.dataset&&(eventTarget.dataset.loader!==LOAD_ORIGIN||eventTarget.dataset.isnonnativesdk!=='true')){return undefined;}const errorMessage=`Error in loading a third-party script from URL ${eventTarget?.src} with ID ${eventTarget?.id}.`;return Object.create(error,{message:{value:errorMessage}});}return error;}catch(e){return e;}};
|
613
592
|
|
614
593
|
/**
|
615
594
|
* A service to handle errors
|
@@ -630,7 +609,7 @@
|
|
630
609
|
* Send handled errors to external error monitoring service via a plugin
|
631
610
|
*
|
632
611
|
* @param {Error} error Error instance from handled error
|
633
|
-
*/notifyError(error,errorState){if(this.pluginEngine&&this.httpClient
|
612
|
+
*/notifyError(error,errorState){if(this.pluginEngine&&this.httpClient){try{this.pluginEngine.invokeSingle('errorReporting.notify',this.pluginEngine,// deprecated parameter
|
634
613
|
this.errReportingClient,// deprecated parameter
|
635
614
|
error,state,this.logger,this.httpClient,errorState);}catch(err){// Not calling onError here as we don't want to go into infinite loop
|
636
615
|
this.logger?.error(NOTIFY_FAILURE_ERROR(ERROR_HANDLER),err);}}}}const defaultErrorHandler=new ErrorHandler(defaultLogger,defaultPluginEngine);
|
@@ -1111,6 +1090,8 @@
|
|
1111
1090
|
|
1112
1091
|
const METRICS_PAYLOAD_VERSION='1';
|
1113
1092
|
|
1093
|
+
const FAILED_REQUEST_ERR_MSG_PREFIX='The request failed';const ERROR_MESSAGES_TO_BE_FILTERED=[FAILED_REQUEST_ERR_MSG_PREFIX];
|
1094
|
+
|
1114
1095
|
// Errors from the below scripts are NOT allowed to reach Bugsnag
|
1115
1096
|
const SDK_FILE_NAME_PREFIXES=()=>['rsa'// Prefix for all the SDK scripts including plugins and module federated chunks
|
1116
1097
|
];const DEV_HOSTS=['www.test-host.com','localhost','127.0.0.1','[::1]'];// List of keys to exclude from the metadata
|
@@ -1118,11 +1099,19 @@
|
|
1118
1099
|
const APP_STATE_EXCLUDE_KEYS=['userId','userTraits','groupId','groupTraits','anonymousId','config','instance',// destination instance objects
|
1119
1100
|
'eventBuffer',// pre-load event buffer (may contain PII)
|
1120
1101
|
'traits'];const REQUEST_TIMEOUT_MS$1=10*1000;// 10 seconds
|
1121
|
-
const NOTIFIER_NAME='RudderStack JavaScript SDK Error Notifier';const SDK_GITHUB_URL='https://github.com/rudderlabs/rudder-sdk-js';const SOURCE_NAME='js';
|
1102
|
+
const NOTIFIER_NAME='RudderStack JavaScript SDK Error Notifier';const SDK_GITHUB_URL='https://github.com/rudderlabs/rudder-sdk-js';const SOURCE_NAME='js';const ERROR_REPORTING_PLUGIN='ErrorReportingPlugin';
|
1122
1103
|
|
1123
1104
|
const getConfigForPayloadCreation=(err,errorType)=>{switch(errorType){case ErrorType.UNHANDLEDEXCEPTION:{const{error}=err;return {component:'unhandledException handler',tolerateNonErrors:true,errorFramesToSkip:1,normalizedError:error||err};}case ErrorType.UNHANDLEDREJECTION:{const error=err;return {component:'unhandledrejection handler',tolerateNonErrors:false,errorFramesToSkip:1,normalizedError:error.reason};}case ErrorType.HANDLEDEXCEPTION:default:return {component:'notify()',tolerateNonErrors:true,errorFramesToSkip:2,normalizedError:err};}};const createNewBreadcrumb=(message,metaData)=>({type:'manual',name:message,timestamp:new Date(),metaData:metaData??{}});const getReleaseStage=()=>{const host=globalThis.location.hostname;return host&&DEV_HOSTS.includes(host)?'development':'production';};const getAppStateForMetadata=state=>{const stateStr=stringifyWithoutCircular(state,false,APP_STATE_EXCLUDE_KEYS);return stateStr!==null?JSON.parse(stateStr):{};};const getURLWithoutQueryString=()=>{const url=globalThis.location.href.split('?');return url[0];};const getErrorContext=event=>{const{message}=event;let context=message;// Hack for easily grouping the script load errors
|
1124
1105
|
// on the dashboard
|
1125
|
-
if(message.includes('Error in loading a third-party script')){context='Script load failures';}return context;};const getBugsnagErrorEvent=(payload,errorState,state)=>({notifier:{name:NOTIFIER_NAME,version:state.context.app.value.version,url:SDK_GITHUB_URL},events:[{payloadVersion:'5',exceptions:clone(payload.errors),severity:errorState.severity,unhandled:errorState.unhandled,severityReason:errorState.severityReason,app:{version:state.context.app.value.version,releaseStage:getReleaseStage()},device:{locale:state.context.locale.value??undefined,userAgent:state.context.userAgent.value??undefined,time:new Date()},request:{url:getURLWithoutQueryString(),clientIp:'[NOT COLLECTED]'},breadcrumbs:clone(state.reporting.breadcrumbs.value),context:getErrorContext(payload.errors[0]),metaData:{sdk:{name:'JS',installType:state.context.app.value.installType},state:getAppStateForMetadata(state)??{},source:{snippetVersion:globalThis.RudderSnippetVersion}},user:{id:state.source.value?.id??state.lifecycle.writeKey.value}}]})
|
1106
|
+
if(message.includes('Error in loading a third-party script')){context='Script load failures';}return context;};const getBugsnagErrorEvent=(payload,errorState,state)=>({notifier:{name:NOTIFIER_NAME,version:state.context.app.value.version,url:SDK_GITHUB_URL},events:[{payloadVersion:'5',exceptions:clone(payload.errors),severity:errorState.severity,unhandled:errorState.unhandled,severityReason:errorState.severityReason,app:{version:state.context.app.value.version,releaseStage:getReleaseStage()},device:{locale:state.context.locale.value??undefined,userAgent:state.context.userAgent.value??undefined,time:new Date()},request:{url:getURLWithoutQueryString(),clientIp:'[NOT COLLECTED]'},breadcrumbs:clone(state.reporting.breadcrumbs.value),context:getErrorContext(payload.errors[0]),metaData:{sdk:{name:'JS',installType:state.context.app.value.installType},state:getAppStateForMetadata(state)??{},source:{snippetVersion:globalThis.RudderSnippetVersion}},user:{id:state.source.value?.id??state.lifecycle.writeKey.value}}]});/**
|
1107
|
+
* A function to determine whether the error should be promoted to notify or not
|
1108
|
+
* @param {Error} error
|
1109
|
+
* @returns
|
1110
|
+
*/const isAllowedToBeNotified=event=>{const errorMessage=event.message;if(errorMessage&&typeof errorMessage==='string'){return !ERROR_MESSAGES_TO_BE_FILTERED.some(e=>errorMessage.includes(e));}return true;};/**
|
1111
|
+
* A function to determine if the error is from Rudder SDK
|
1112
|
+
* @param {Error} event
|
1113
|
+
* @returns
|
1114
|
+
*/const isRudderSDKError=event=>{const errorOrigin=event.stacktrace?.[0]?.file;if(!errorOrigin||typeof errorOrigin!=='string'){return false;}const srcFileName=errorOrigin.substring(errorOrigin.lastIndexOf('/')+1);const paths=errorOrigin.split('/');// extract the parent folder name from the error origin file path
|
1126
1115
|
// Ex: parentFolderName will be 'sample' for url: https://example.com/sample/file.min.js
|
1127
1116
|
const parentFolderName=paths[paths.length-2];return parentFolderName===CDN_INT_DIR||SDK_FILE_NAME_PREFIXES().some(prefix=>srcFileName.startsWith(prefix)&&srcFileName.endsWith('.js'));};const getErrorDeliveryPayload=(payload,state)=>{const data={version:METRICS_PAYLOAD_VERSION,message_id:generateUUID(),source:{name:SOURCE_NAME,sdk_version:state.context.app.value.version,write_key:state.lifecycle.writeKey.value,install_type:state.context.app.value.installType},errors:payload};return stringifyWithoutCircular(data);};
|
1128
1117
|
|
@@ -1166,19 +1155,10 @@
|
|
1166
1155
|
// This adds one.
|
1167
1156
|
if(f.lineNumber>-1&&!f.file&&!f.method){f.file='global code';}return f;};const ensureString=str=>typeof str==='string'?str:'';function createBugsnagError(errorClass,errorMessage,stacktrace){return {errorClass:ensureString(errorClass),message:ensureString(errorMessage),type:'browserjs',stacktrace:stacktrace.reduce((accum,frame)=>{const f=formatStackframe(frame);// don't include a stackframe if none of its properties are defined
|
1168
1157
|
try{if(JSON.stringify(f)==='{}')return accum;return accum.concat(f);}catch(e){return accum;}},[])};}// Helpers
|
1169
|
-
const getStacktrace=(error,errorFramesToSkip)=>{if(hasStack(error))return ErrorStackParser.parse(error).slice(errorFramesToSkip);return [];};const hasNecessaryFields=error=>(typeof error.name==='string'||typeof error.errorClass==='string')&&(typeof error.message==='string'||typeof error.errorMessage==='string');const normaliseError=(maybeError,
|
1170
|
-
//
|
1171
|
-
// - the promise rejection handler (both in the browser and node)
|
1172
|
-
// - the node uncaughtException handler
|
1173
|
-
//
|
1174
|
-
// We are really limited in what we can do to get a stacktrace. So we use the
|
1175
|
-
// tolerateNonErrors option to ensure that the resulting error communicates as
|
1176
|
-
// such.
|
1177
|
-
if(!tolerateNonErrors){if(isError(maybeError)){error=maybeError;}else {error=createAndLogInputError(typeof maybeError);internalFrames+=2;}}else {switch(typeof maybeError){case'string':case'number':case'boolean':error=new Error(String(maybeError));internalFrames+=1;break;case'function':error=createAndLogInputError('function');internalFrames+=2;break;case'object':if(maybeError!==null&&isError(maybeError)){error=maybeError;}else if(maybeError!==null&&hasNecessaryFields(maybeError)){error=new Error(maybeError.message||maybeError.errorMessage);error.name=maybeError.name||maybeError.errorClass;internalFrames+=1;}else {error=createAndLogInputError(maybeError===null?'null':'unsupported object');internalFrames+=2;}break;default:error=createAndLogInputError('nothing');internalFrames+=2;}}if(!hasStack(error)){// in IE10/11 a new Error() doesn't have a stacktrace until you throw it, so try that here
|
1158
|
+
const getStacktrace=(error,errorFramesToSkip)=>{if(hasStack(error))return ErrorStackParser.parse(error).slice(errorFramesToSkip);return [];};const hasNecessaryFields=error=>(typeof error.name==='string'||typeof error.errorClass==='string')&&(typeof error.message==='string'||typeof error.errorMessage==='string');const normaliseError=(maybeError,component,logger)=>{let error;let internalFrames=0;if(isError(maybeError)){error=maybeError;}else if(typeof maybeError==='object'&&hasNecessaryFields(maybeError)){error=new Error(maybeError.message||maybeError.errorMessage);error.name=maybeError.name||maybeError.errorClass;internalFrames+=1;}else {logger?.warn(`${ERROR_REPORTING_PLUGIN}:: ${component} received a non-error: ${stringifyWithoutCircular(error)}`);error=undefined;}if(error&&!hasStack(error)){// in IE10/11 a new Error() doesn't have a stacktrace until you throw it, so try that here
|
1178
1159
|
try{throw error;}catch(e){if(hasStack(e)){error=e;// if the error only got a stacktrace after we threw it here, we know it
|
1179
|
-
// will only have one extra internal frame from this function
|
1180
|
-
|
1181
|
-
internalFrames=1;}}}return [error,internalFrames];};class ErrorFormat{constructor(errorClass,errorMessage,stacktrace){this.errors=[createBugsnagError(errorClass,errorMessage,stacktrace)];}static create(maybeError,tolerateNonErrors,handledState,component,errorFramesToSkip=0,logger){const[error,internalFrames]=normaliseError(maybeError,tolerateNonErrors,component,logger);let event;try{const stacktrace=getStacktrace(error,// if an error was created/throw in the normaliseError() function, we need to
|
1160
|
+
// will only have one extra internal frame from this function
|
1161
|
+
internalFrames=1;}}}return [error,internalFrames];};class ErrorFormat{constructor(errorClass,errorMessage,stacktrace){this.errors=[createBugsnagError(errorClass,errorMessage,stacktrace)];}static create(maybeError,tolerateNonErrors,handledState,component,errorFramesToSkip=0,logger){const[error,internalFrames]=normaliseError(maybeError,component,logger);if(!error){return undefined;}let event;try{const stacktrace=getStacktrace(error,// if an error was created/throw in the normaliseError() function, we need to
|
1182
1162
|
// tell the getStacktrace() function to skip the number of frames we know will
|
1183
1163
|
// be from our own functions. This is added to the number of frames deep we
|
1184
1164
|
// were told about
|
@@ -1189,7 +1169,7 @@
|
|
1189
1169
|
const pluginName$9='ErrorReporting';const ErrorReporting=()=>({name:pluginName$9,deps:[],initialize:state=>{state.plugins.loadedPlugins.value=[...state.plugins.loadedPlugins.value,pluginName$9];state.reporting.isErrorReportingPluginLoaded.value=true;if(state.reporting.breadcrumbs?.value){state.reporting.breadcrumbs.value=[createNewBreadcrumb('Error Reporting Plugin Loaded')];}},errorReporting:{// This extension point is deprecated
|
1190
1170
|
// TODO: Remove this in the next major release
|
1191
1171
|
init:(state,pluginEngine,externalSrcLoader,logger,isInvokedFromLatestCore)=>{if(isInvokedFromLatestCore){return undefined;}if(!state.source.value?.config||!state.source.value?.id){return Promise.reject(new Error(INVALID_SOURCE_CONFIG_ERROR));}return pluginEngine.invokeSingle('errorReportingProvider.init',state,externalSrcLoader,logger);},notify:(pluginEngine,client,error,state,logger,httpClient,errorState)=>{if(httpClient){const{component,tolerateNonErrors,errorFramesToSkip,normalizedError}=getConfigForPayloadCreation(error,errorState?.severityReason.type);// Generate the error payload
|
1192
|
-
const errorPayload=ErrorFormat.create(normalizedError,tolerateNonErrors,errorState,component,errorFramesToSkip,logger)
|
1172
|
+
const errorPayload=ErrorFormat.create(normalizedError,tolerateNonErrors,errorState,component,errorFramesToSkip,logger);if(!errorPayload||!isAllowedToBeNotified(errorPayload.errors[0])){return;}// filter errors
|
1193
1173
|
if(!isRudderSDKError(errorPayload.errors[0])){return;}// enrich error payload
|
1194
1174
|
const bugsnagPayload=getBugsnagErrorEvent(errorPayload,errorState,state);// send it to metrics service
|
1195
1175
|
httpClient?.getAsyncData({url:state.metrics.metricsServiceUrl.value,options:{method:'POST',data:getErrorDeliveryPayload(bugsnagPayload,state),sendRawData:true},isRawResponse:true,timeout:REQUEST_TIMEOUT_MS$1,callback:(result,details)=>{// do nothing
|
@@ -2708,9 +2688,14 @@
|
|
2708
2688
|
*/const getUrlWithoutHash=url=>{let urlWithoutHash=url;try{const urlObj=new URL(url);urlWithoutHash=urlObj.origin+urlObj.pathname+urlObj.search;}catch(error){// Do nothing
|
2709
2689
|
}return urlWithoutHash;};
|
2710
2690
|
|
2691
|
+
/**
|
2692
|
+
* Determines if the SDK is running inside a chrome extension
|
2693
|
+
* @returns boolean
|
2694
|
+
*/const isSDKRunningInChromeExtension=()=>!!(window.chrome&&window.chrome.runtime&&window.chrome.runtime.id);
|
2695
|
+
|
2711
2696
|
const DEFAULT_PRE_CONSENT_STORAGE_STRATEGY='none';const DEFAULT_PRE_CONSENT_EVENTS_DELIVERY_TYPE='immediate';
|
2712
2697
|
|
2713
|
-
const isMetricsReportingEnabled=sourceConfig=>sourceConfig?.statsCollection?.metrics?.enabled===true;
|
2698
|
+
const isErrorReportingEnabled=sourceConfig=>sourceConfig?.statsCollection?.errors?.enabled===true;const isMetricsReportingEnabled=sourceConfig=>sourceConfig?.statsCollection?.metrics?.enabled===true;
|
2714
2699
|
|
2715
2700
|
/**
|
2716
2701
|
* Validates and normalizes the consent options provided by the user
|
@@ -2744,10 +2729,7 @@
|
|
2744
2729
|
* Updates the reporting state variables from the source config data
|
2745
2730
|
* @param res Source config
|
2746
2731
|
* @param logger Logger instance
|
2747
|
-
*/const updateReportingState=res=>{state.reporting.isErrorReportingEnabled.value=
|
2748
|
-
// state.reporting.isErrorReportingEnabled.value =
|
2749
|
-
// isErrorReportingEnabled(res.source.config) && !isSDKRunningInChromeExtension();
|
2750
|
-
state.reporting.isMetricsReportingEnabled.value=isMetricsReportingEnabled(res.source.config);};const updateStorageStateFromLoadOptions=logger=>{const{useServerSideCookies,dataServiceEndpoint,storage:storageOptsFromLoad,setCookieDomain,sameDomainCookiesOnly}=state.loadOptions.value;let storageType=storageOptsFromLoad?.type;if(isDefined(storageType)&&!isValidStorageType(storageType)){logger?.warn(STORAGE_TYPE_VALIDATION_WARNING(CONFIG_MANAGER,storageType,DEFAULT_STORAGE_TYPE));storageType=DEFAULT_STORAGE_TYPE;}let storageEncryptionVersion=storageOptsFromLoad?.encryption?.version;const encryptionPluginName=storageEncryptionVersion&&StorageEncryptionVersionsToPluginNameMap[storageEncryptionVersion];if(!isUndefined(storageEncryptionVersion)&&isUndefined(encryptionPluginName)){// set the default encryption plugin
|
2732
|
+
*/const updateReportingState=res=>{state.reporting.isErrorReportingEnabled.value=isErrorReportingEnabled(res.source.config)&&!isSDKRunningInChromeExtension();state.reporting.isMetricsReportingEnabled.value=isMetricsReportingEnabled(res.source.config);};const updateStorageStateFromLoadOptions=logger=>{const{useServerSideCookies,dataServiceEndpoint,storage:storageOptsFromLoad,setCookieDomain,sameDomainCookiesOnly}=state.loadOptions.value;let storageType=storageOptsFromLoad?.type;if(isDefined(storageType)&&!isValidStorageType(storageType)){logger?.warn(STORAGE_TYPE_VALIDATION_WARNING(CONFIG_MANAGER,storageType,DEFAULT_STORAGE_TYPE));storageType=DEFAULT_STORAGE_TYPE;}let storageEncryptionVersion=storageOptsFromLoad?.encryption?.version;const encryptionPluginName=storageEncryptionVersion&&StorageEncryptionVersionsToPluginNameMap[storageEncryptionVersion];if(!isUndefined(storageEncryptionVersion)&&isUndefined(encryptionPluginName)){// set the default encryption plugin
|
2751
2733
|
logger?.warn(UNSUPPORTED_STORAGE_ENCRYPTION_VERSION_WARNING(CONFIG_MANAGER,storageEncryptionVersion,StorageEncryptionVersionsToPluginNameMap,DEFAULT_STORAGE_ENCRYPTION_VERSION));storageEncryptionVersion=DEFAULT_STORAGE_ENCRYPTION_VERSION;}else if(isUndefined(storageEncryptionVersion)){storageEncryptionVersion=DEFAULT_STORAGE_ENCRYPTION_VERSION;}// Allow migration only if the configured encryption version is the default encryption version
|
2752
2734
|
const configuredMigrationValue=storageOptsFromLoad?.migrate;const finalMigrationVal=configuredMigrationValue&&storageEncryptionVersion===DEFAULT_STORAGE_ENCRYPTION_VERSION;if(configuredMigrationValue===true&&finalMigrationVal!==configuredMigrationValue){logger?.warn(STORAGE_DATA_MIGRATION_OVERRIDE_WARNING(CONFIG_MANAGER,storageEncryptionVersion,DEFAULT_STORAGE_ENCRYPTION_VERSION));}r(()=>{state.storage.type.value=storageType;let cookieOptions=storageOptsFromLoad?.cookie??{};if(useServerSideCookies){state.serverCookies.isEnabledServerSideCookies.value=useServerSideCookies;const providedCookieDomain=cookieOptions.domain??setCookieDomain;/**
|
2753
2735
|
* Based on the following conditions, we decide whether to use the exact domain or not to determine the data service URL:
|
@@ -361,7 +361,7 @@ payload.groupId=tryStringify(payload.groupId);if(isObjectLiteralAndNotNull(paylo
|
|
361
361
|
|
362
362
|
const CAPABILITIES_MANAGER='CapabilitiesManager';const CONFIG_MANAGER='ConfigManager';const EVENT_MANAGER='EventManager';const PLUGINS_MANAGER='PluginsManager';const USER_SESSION_MANAGER='UserSessionManager';const ERROR_HANDLER='ErrorHandler';const PLUGIN_ENGINE='PluginEngine';const STORE_MANAGER='StoreManager';const READY_API='readyApi';const EVENT_REPOSITORY='EventRepository';const EXTERNAL_SRC_LOADER='ExternalSrcLoader';const HTTP_CLIENT='HttpClient';const RS_APP='RudderStackApplication';const ANALYTICS_CORE='AnalyticsCore';
|
363
363
|
|
364
|
-
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.7.
|
364
|
+
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.7.8';const APP_NAMESPACE='com.rudderlabs.javascript';const MODULE_TYPE='npm';const ADBLOCK_PAGE_CATEGORY='RudderJS-Initiated';const ADBLOCK_PAGE_NAME='ad-block page request';const ADBLOCK_PAGE_PATH='/ad-blocked';const GLOBAL_PRELOAD_BUFFER='preloadedEventsBuffer';const CONSENT_TRACK_EVENT_NAME='Consent Management Interaction';
|
365
365
|
|
366
366
|
const QUERY_PARAM_TRAIT_PREFIX='ajs_trait_';const QUERY_PARAM_PROPERTY_PREFIX='ajs_prop_';const QUERY_PARAM_ANONYMOUS_ID_KEY='ajs_aid';const QUERY_PARAM_USER_ID_KEY='ajs_uid';const QUERY_PARAM_TRACK_EVENT_NAME_KEY='ajs_event';
|
367
367
|
|
@@ -566,35 +566,14 @@ processRawPlugins(callback){callback(this.plugins);this.cache={};}invoke(extPoin
|
|
566
566
|
extensionPointName=extensionPointName.replace(/(^!|!$)/g,'');if(!extensionPointName){throw new Error(PLUGIN_EXT_POINT_INVALID_ERROR);}const extensionPointNameParts=extensionPointName.split('.');extensionPointNameParts.pop();const pluginMethodPath=extensionPointNameParts.join('.');const pluginsToInvoke=allowMultiple?this.getPlugins(extensionPointName):[this.getPlugins(extensionPointName)[0]];return pluginsToInvoke.map(plugin=>{const method=getValueByPath(plugin,extensionPointName);if(!isFunction(method)||noCall){return method;}try{return method.apply(getValueByPath(plugin,pluginMethodPath),args);}catch(err){// When a plugin failed, doesn't break the app
|
567
567
|
if(throws){throw err;}else {this.logger?.error(PLUGIN_INVOCATION_ERROR(PLUGIN_ENGINE,extensionPointName,plugin.name),err);}}return null;});}invokeSingle(extPoint,...args){return this.invoke(extPoint,false,...args)[0];}invokeMultiple(extPoint,...args){return this.invoke(extPoint,true,...args);}}const defaultPluginEngine=new PluginEngine({throws:true},defaultLogger);
|
568
568
|
|
569
|
-
const
|
569
|
+
const LOAD_ORIGIN='RS_JS_SDK';
|
570
570
|
|
571
571
|
/**
|
572
572
|
* Utility method to normalise errors
|
573
573
|
*/const processError=error=>{let errorMessage;try{if(isString(error)){errorMessage=error;}else if(error instanceof Error){errorMessage=error.message;}else if(error instanceof ErrorEvent){errorMessage=error.message;}else {errorMessage=error.message?error.message:stringifyWithoutCircular(error);}}catch(e){errorMessage=`Unknown error: ${e.message}`;}return errorMessage;};const getNormalizedErrorForUnhandledError=error=>{try{if(error instanceof Error||error instanceof ErrorEvent||error instanceof PromiseRejectionEvent&&error.reason){return error;}// TODO: remove this block once all device mode integrations start using the v3 script loader module (TS)
|
574
|
-
|
575
|
-
//
|
576
|
-
|
577
|
-
// if (eventTarget && eventTarget.localName !== 'script') {
|
578
|
-
// return undefined;
|
579
|
-
// }
|
580
|
-
// // Discard script errors that are not originated at SDK or from native SDKs
|
581
|
-
// if (
|
582
|
-
// eventTarget?.dataset &&
|
583
|
-
// (eventTarget.dataset.loader !== LOAD_ORIGIN ||
|
584
|
-
// eventTarget.dataset.isnonnativesdk !== 'true')
|
585
|
-
// ) {
|
586
|
-
// return undefined;
|
587
|
-
// }
|
588
|
-
// const errorMessage = `Error in loading a third-party script from URL ${eventTarget?.src} with ID ${eventTarget?.id}.`;
|
589
|
-
// return Object.create(error, {
|
590
|
-
// message: { value: errorMessage },
|
591
|
-
// });
|
592
|
-
// }
|
593
|
-
return undefined;}catch(e){return e;}};/**
|
594
|
-
* A function to determine whether the error should be promoted to notify or not
|
595
|
-
* @param {Error} error
|
596
|
-
* @returns
|
597
|
-
*/const isAllowedToBeNotified=error=>{if((error instanceof Error||error instanceof ErrorEvent)&&error.message){return !ERROR_MESSAGES_TO_BE_FILTERED.some(e=>error.message.includes(e));}if(error instanceof PromiseRejectionEvent&&typeof error.reason==='string'){return !ERROR_MESSAGES_TO_BE_FILTERED.some(e=>error.reason.includes(e));}return true;};
|
574
|
+
if(error instanceof Event){const eventTarget=error.target;// Discard all the non-script loading errors
|
575
|
+
if(eventTarget&&eventTarget.localName!=='script'){return undefined;}// Discard script errors that are not originated at SDK or from native SDKs
|
576
|
+
if(eventTarget?.dataset&&(eventTarget.dataset.loader!==LOAD_ORIGIN||eventTarget.dataset.isnonnativesdk!=='true')){return undefined;}const errorMessage=`Error in loading a third-party script from URL ${eventTarget?.src} with ID ${eventTarget?.id}.`;return Object.create(error,{message:{value:errorMessage}});}return error;}catch(e){return e;}};
|
598
577
|
|
599
578
|
/**
|
600
579
|
* A service to handle errors
|
@@ -615,7 +594,7 @@ breadcrumb,this.logger,state);}catch(err){this.onError(err,ERROR_HANDLER,'errorR
|
|
615
594
|
* Send handled errors to external error monitoring service via a plugin
|
616
595
|
*
|
617
596
|
* @param {Error} error Error instance from handled error
|
618
|
-
*/notifyError(error,errorState){if(this.pluginEngine&&this.httpClient
|
597
|
+
*/notifyError(error,errorState){if(this.pluginEngine&&this.httpClient){try{this.pluginEngine.invokeSingle('errorReporting.notify',this.pluginEngine,// deprecated parameter
|
619
598
|
this.errReportingClient,// deprecated parameter
|
620
599
|
error,state,this.logger,this.httpClient,errorState);}catch(err){// Not calling onError here as we don't want to go into infinite loop
|
621
600
|
this.logger?.error(NOTIFY_FAILURE_ERROR(ERROR_HANDLER),err);}}}}const defaultErrorHandler=new ErrorHandler(defaultLogger,defaultPluginEngine);
|
@@ -782,6 +761,8 @@ unregisterLocalPlugins(){Object.values(pluginsInventory).forEach(localPlugin=>{t
|
|
782
761
|
* Utility to parse XHR JSON response
|
783
762
|
*/const responseTextToJson=(responseText,onError)=>{try{return JSON.parse(responseText||'');}catch(err){const error=getMutatedError(err,'Failed to parse response data');if(isFunction(onError)){onError(error);}else {throw error;}}return undefined;};
|
784
763
|
|
764
|
+
const FAILED_REQUEST_ERR_MSG_PREFIX='The request failed';
|
765
|
+
|
785
766
|
const DEFAULT_XHR_REQUEST_OPTIONS={headers:{Accept:'application/json','Content-Type':'application/json;charset=UTF-8'},method:'GET'};/**
|
786
767
|
* Utility to create request configuration based on default options
|
787
768
|
*/const createXhrRequestOptions=(url,options,basicAuthHeader)=>{const requestOptions=mergeDeepRight(DEFAULT_XHR_REQUEST_OPTIONS,options||{});if(basicAuthHeader){requestOptions.headers=mergeDeepRight(requestOptions.headers,{Authorization:basicAuthHeader});}requestOptions.url=url;return requestOptions;};/**
|
@@ -1053,9 +1034,14 @@ if(utmParam==='campaign'){utmParam='name';}result[utmParam]=value;}});}catch(err
|
|
1053
1034
|
*/const getUrlWithoutHash=url=>{let urlWithoutHash=url;try{const urlObj=new URL(url);urlWithoutHash=urlObj.origin+urlObj.pathname+urlObj.search;}catch(error){// Do nothing
|
1054
1035
|
}return urlWithoutHash;};
|
1055
1036
|
|
1037
|
+
/**
|
1038
|
+
* Determines if the SDK is running inside a chrome extension
|
1039
|
+
* @returns boolean
|
1040
|
+
*/const isSDKRunningInChromeExtension=()=>!!(window.chrome&&window.chrome.runtime&&window.chrome.runtime.id);
|
1041
|
+
|
1056
1042
|
const DEFAULT_PRE_CONSENT_STORAGE_STRATEGY='none';const DEFAULT_PRE_CONSENT_EVENTS_DELIVERY_TYPE='immediate';
|
1057
1043
|
|
1058
|
-
const isMetricsReportingEnabled=sourceConfig=>sourceConfig?.statsCollection?.metrics?.enabled===true;
|
1044
|
+
const isErrorReportingEnabled=sourceConfig=>sourceConfig?.statsCollection?.errors?.enabled===true;const isMetricsReportingEnabled=sourceConfig=>sourceConfig?.statsCollection?.metrics?.enabled===true;
|
1059
1045
|
|
1060
1046
|
const DEFAULT_INTEGRATIONS_CONFIG={All:true};
|
1061
1047
|
|
@@ -1091,10 +1077,7 @@ for(const script of scripts){const src=script.getAttribute('src');if(src&&sdkFil
|
|
1091
1077
|
* Updates the reporting state variables from the source config data
|
1092
1078
|
* @param res Source config
|
1093
1079
|
* @param logger Logger instance
|
1094
|
-
*/const updateReportingState=res=>{state.reporting.isErrorReportingEnabled.value=
|
1095
|
-
// state.reporting.isErrorReportingEnabled.value =
|
1096
|
-
// isErrorReportingEnabled(res.source.config) && !isSDKRunningInChromeExtension();
|
1097
|
-
state.reporting.isMetricsReportingEnabled.value=isMetricsReportingEnabled(res.source.config);};const updateStorageStateFromLoadOptions=logger=>{const{useServerSideCookies,dataServiceEndpoint,storage:storageOptsFromLoad,setCookieDomain,sameDomainCookiesOnly}=state.loadOptions.value;let storageType=storageOptsFromLoad?.type;if(isDefined(storageType)&&!isValidStorageType(storageType)){logger?.warn(STORAGE_TYPE_VALIDATION_WARNING(CONFIG_MANAGER,storageType,DEFAULT_STORAGE_TYPE));storageType=DEFAULT_STORAGE_TYPE;}let storageEncryptionVersion=storageOptsFromLoad?.encryption?.version;const encryptionPluginName=storageEncryptionVersion&&StorageEncryptionVersionsToPluginNameMap[storageEncryptionVersion];if(!isUndefined(storageEncryptionVersion)&&isUndefined(encryptionPluginName)){// set the default encryption plugin
|
1080
|
+
*/const updateReportingState=res=>{state.reporting.isErrorReportingEnabled.value=isErrorReportingEnabled(res.source.config)&&!isSDKRunningInChromeExtension();state.reporting.isMetricsReportingEnabled.value=isMetricsReportingEnabled(res.source.config);};const updateStorageStateFromLoadOptions=logger=>{const{useServerSideCookies,dataServiceEndpoint,storage:storageOptsFromLoad,setCookieDomain,sameDomainCookiesOnly}=state.loadOptions.value;let storageType=storageOptsFromLoad?.type;if(isDefined(storageType)&&!isValidStorageType(storageType)){logger?.warn(STORAGE_TYPE_VALIDATION_WARNING(CONFIG_MANAGER,storageType,DEFAULT_STORAGE_TYPE));storageType=DEFAULT_STORAGE_TYPE;}let storageEncryptionVersion=storageOptsFromLoad?.encryption?.version;const encryptionPluginName=storageEncryptionVersion&&StorageEncryptionVersionsToPluginNameMap[storageEncryptionVersion];if(!isUndefined(storageEncryptionVersion)&&isUndefined(encryptionPluginName)){// set the default encryption plugin
|
1098
1081
|
logger?.warn(UNSUPPORTED_STORAGE_ENCRYPTION_VERSION_WARNING(CONFIG_MANAGER,storageEncryptionVersion,StorageEncryptionVersionsToPluginNameMap,DEFAULT_STORAGE_ENCRYPTION_VERSION));storageEncryptionVersion=DEFAULT_STORAGE_ENCRYPTION_VERSION;}else if(isUndefined(storageEncryptionVersion)){storageEncryptionVersion=DEFAULT_STORAGE_ENCRYPTION_VERSION;}// Allow migration only if the configured encryption version is the default encryption version
|
1099
1082
|
const configuredMigrationValue=storageOptsFromLoad?.migrate;const finalMigrationVal=configuredMigrationValue&&storageEncryptionVersion===DEFAULT_STORAGE_ENCRYPTION_VERSION;if(configuredMigrationValue===true&&finalMigrationVal!==configuredMigrationValue){logger?.warn(STORAGE_DATA_MIGRATION_OVERRIDE_WARNING(CONFIG_MANAGER,storageEncryptionVersion,DEFAULT_STORAGE_ENCRYPTION_VERSION));}r(()=>{state.storage.type.value=storageType;let cookieOptions=storageOptsFromLoad?.cookie??{};if(useServerSideCookies){state.serverCookies.isEnabledServerSideCookies.value=useServerSideCookies;const providedCookieDomain=cookieOptions.domain??setCookieDomain;/**
|
1100
1083
|
* Based on the following conditions, we decide whether to use the exact domain or not to determine the data service URL:
|
@@ -367,7 +367,7 @@
|
|
367
367
|
|
368
368
|
const CAPABILITIES_MANAGER='CapabilitiesManager';const CONFIG_MANAGER='ConfigManager';const EVENT_MANAGER='EventManager';const PLUGINS_MANAGER='PluginsManager';const USER_SESSION_MANAGER='UserSessionManager';const ERROR_HANDLER='ErrorHandler';const PLUGIN_ENGINE='PluginEngine';const STORE_MANAGER='StoreManager';const READY_API='readyApi';const EVENT_REPOSITORY='EventRepository';const EXTERNAL_SRC_LOADER='ExternalSrcLoader';const HTTP_CLIENT='HttpClient';const RS_APP='RudderStackApplication';const ANALYTICS_CORE='AnalyticsCore';
|
369
369
|
|
370
|
-
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.7.
|
370
|
+
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.7.8';const APP_NAMESPACE='com.rudderlabs.javascript';const MODULE_TYPE='npm';const ADBLOCK_PAGE_CATEGORY='RudderJS-Initiated';const ADBLOCK_PAGE_NAME='ad-block page request';const ADBLOCK_PAGE_PATH='/ad-blocked';const GLOBAL_PRELOAD_BUFFER='preloadedEventsBuffer';const CONSENT_TRACK_EVENT_NAME='Consent Management Interaction';
|
371
371
|
|
372
372
|
const QUERY_PARAM_TRAIT_PREFIX='ajs_trait_';const QUERY_PARAM_PROPERTY_PREFIX='ajs_prop_';const QUERY_PARAM_ANONYMOUS_ID_KEY='ajs_aid';const QUERY_PARAM_USER_ID_KEY='ajs_uid';const QUERY_PARAM_TRACK_EVENT_NAME_KEY='ajs_event';
|
373
373
|
|
@@ -572,35 +572,14 @@
|
|
572
572
|
extensionPointName=extensionPointName.replace(/(^!|!$)/g,'');if(!extensionPointName){throw new Error(PLUGIN_EXT_POINT_INVALID_ERROR);}const extensionPointNameParts=extensionPointName.split('.');extensionPointNameParts.pop();const pluginMethodPath=extensionPointNameParts.join('.');const pluginsToInvoke=allowMultiple?this.getPlugins(extensionPointName):[this.getPlugins(extensionPointName)[0]];return pluginsToInvoke.map(plugin=>{const method=getValueByPath(plugin,extensionPointName);if(!isFunction(method)||noCall){return method;}try{return method.apply(getValueByPath(plugin,pluginMethodPath),args);}catch(err){// When a plugin failed, doesn't break the app
|
573
573
|
if(throws){throw err;}else {this.logger?.error(PLUGIN_INVOCATION_ERROR(PLUGIN_ENGINE,extensionPointName,plugin.name),err);}}return null;});}invokeSingle(extPoint,...args){return this.invoke(extPoint,false,...args)[0];}invokeMultiple(extPoint,...args){return this.invoke(extPoint,true,...args);}}const defaultPluginEngine=new PluginEngine({throws:true},defaultLogger);
|
574
574
|
|
575
|
-
const
|
575
|
+
const LOAD_ORIGIN='RS_JS_SDK';
|
576
576
|
|
577
577
|
/**
|
578
578
|
* Utility method to normalise errors
|
579
579
|
*/const processError=error=>{let errorMessage;try{if(isString(error)){errorMessage=error;}else if(error instanceof Error){errorMessage=error.message;}else if(error instanceof ErrorEvent){errorMessage=error.message;}else {errorMessage=error.message?error.message:stringifyWithoutCircular(error);}}catch(e){errorMessage=`Unknown error: ${e.message}`;}return errorMessage;};const getNormalizedErrorForUnhandledError=error=>{try{if(error instanceof Error||error instanceof ErrorEvent||error instanceof PromiseRejectionEvent&&error.reason){return error;}// TODO: remove this block once all device mode integrations start using the v3 script loader module (TS)
|
580
|
-
|
581
|
-
//
|
582
|
-
|
583
|
-
// if (eventTarget && eventTarget.localName !== 'script') {
|
584
|
-
// return undefined;
|
585
|
-
// }
|
586
|
-
// // Discard script errors that are not originated at SDK or from native SDKs
|
587
|
-
// if (
|
588
|
-
// eventTarget?.dataset &&
|
589
|
-
// (eventTarget.dataset.loader !== LOAD_ORIGIN ||
|
590
|
-
// eventTarget.dataset.isnonnativesdk !== 'true')
|
591
|
-
// ) {
|
592
|
-
// return undefined;
|
593
|
-
// }
|
594
|
-
// const errorMessage = `Error in loading a third-party script from URL ${eventTarget?.src} with ID ${eventTarget?.id}.`;
|
595
|
-
// return Object.create(error, {
|
596
|
-
// message: { value: errorMessage },
|
597
|
-
// });
|
598
|
-
// }
|
599
|
-
return undefined;}catch(e){return e;}};/**
|
600
|
-
* A function to determine whether the error should be promoted to notify or not
|
601
|
-
* @param {Error} error
|
602
|
-
* @returns
|
603
|
-
*/const isAllowedToBeNotified=error=>{if((error instanceof Error||error instanceof ErrorEvent)&&error.message){return !ERROR_MESSAGES_TO_BE_FILTERED.some(e=>error.message.includes(e));}if(error instanceof PromiseRejectionEvent&&typeof error.reason==='string'){return !ERROR_MESSAGES_TO_BE_FILTERED.some(e=>error.reason.includes(e));}return true;};
|
580
|
+
if(error instanceof Event){const eventTarget=error.target;// Discard all the non-script loading errors
|
581
|
+
if(eventTarget&&eventTarget.localName!=='script'){return undefined;}// Discard script errors that are not originated at SDK or from native SDKs
|
582
|
+
if(eventTarget?.dataset&&(eventTarget.dataset.loader!==LOAD_ORIGIN||eventTarget.dataset.isnonnativesdk!=='true')){return undefined;}const errorMessage=`Error in loading a third-party script from URL ${eventTarget?.src} with ID ${eventTarget?.id}.`;return Object.create(error,{message:{value:errorMessage}});}return error;}catch(e){return e;}};
|
604
583
|
|
605
584
|
/**
|
606
585
|
* A service to handle errors
|
@@ -621,7 +600,7 @@
|
|
621
600
|
* Send handled errors to external error monitoring service via a plugin
|
622
601
|
*
|
623
602
|
* @param {Error} error Error instance from handled error
|
624
|
-
*/notifyError(error,errorState){if(this.pluginEngine&&this.httpClient
|
603
|
+
*/notifyError(error,errorState){if(this.pluginEngine&&this.httpClient){try{this.pluginEngine.invokeSingle('errorReporting.notify',this.pluginEngine,// deprecated parameter
|
625
604
|
this.errReportingClient,// deprecated parameter
|
626
605
|
error,state,this.logger,this.httpClient,errorState);}catch(err){// Not calling onError here as we don't want to go into infinite loop
|
627
606
|
this.logger?.error(NOTIFY_FAILURE_ERROR(ERROR_HANDLER),err);}}}}const defaultErrorHandler=new ErrorHandler(defaultLogger,defaultPluginEngine);
|
@@ -788,6 +767,8 @@
|
|
788
767
|
* Utility to parse XHR JSON response
|
789
768
|
*/const responseTextToJson=(responseText,onError)=>{try{return JSON.parse(responseText||'');}catch(err){const error=getMutatedError(err,'Failed to parse response data');if(isFunction(onError)){onError(error);}else {throw error;}}return undefined;};
|
790
769
|
|
770
|
+
const FAILED_REQUEST_ERR_MSG_PREFIX='The request failed';
|
771
|
+
|
791
772
|
const DEFAULT_XHR_REQUEST_OPTIONS={headers:{Accept:'application/json','Content-Type':'application/json;charset=UTF-8'},method:'GET'};/**
|
792
773
|
* Utility to create request configuration based on default options
|
793
774
|
*/const createXhrRequestOptions=(url,options,basicAuthHeader)=>{const requestOptions=mergeDeepRight(DEFAULT_XHR_REQUEST_OPTIONS,options||{});if(basicAuthHeader){requestOptions.headers=mergeDeepRight(requestOptions.headers,{Authorization:basicAuthHeader});}requestOptions.url=url;return requestOptions;};/**
|
@@ -1059,9 +1040,14 @@
|
|
1059
1040
|
*/const getUrlWithoutHash=url=>{let urlWithoutHash=url;try{const urlObj=new URL(url);urlWithoutHash=urlObj.origin+urlObj.pathname+urlObj.search;}catch(error){// Do nothing
|
1060
1041
|
}return urlWithoutHash;};
|
1061
1042
|
|
1043
|
+
/**
|
1044
|
+
* Determines if the SDK is running inside a chrome extension
|
1045
|
+
* @returns boolean
|
1046
|
+
*/const isSDKRunningInChromeExtension=()=>!!(window.chrome&&window.chrome.runtime&&window.chrome.runtime.id);
|
1047
|
+
|
1062
1048
|
const DEFAULT_PRE_CONSENT_STORAGE_STRATEGY='none';const DEFAULT_PRE_CONSENT_EVENTS_DELIVERY_TYPE='immediate';
|
1063
1049
|
|
1064
|
-
const isMetricsReportingEnabled=sourceConfig=>sourceConfig?.statsCollection?.metrics?.enabled===true;
|
1050
|
+
const isErrorReportingEnabled=sourceConfig=>sourceConfig?.statsCollection?.errors?.enabled===true;const isMetricsReportingEnabled=sourceConfig=>sourceConfig?.statsCollection?.metrics?.enabled===true;
|
1065
1051
|
|
1066
1052
|
const DEFAULT_INTEGRATIONS_CONFIG={All:true};
|
1067
1053
|
|
@@ -1097,10 +1083,7 @@
|
|
1097
1083
|
* Updates the reporting state variables from the source config data
|
1098
1084
|
* @param res Source config
|
1099
1085
|
* @param logger Logger instance
|
1100
|
-
*/const updateReportingState=res=>{state.reporting.isErrorReportingEnabled.value=
|
1101
|
-
// state.reporting.isErrorReportingEnabled.value =
|
1102
|
-
// isErrorReportingEnabled(res.source.config) && !isSDKRunningInChromeExtension();
|
1103
|
-
state.reporting.isMetricsReportingEnabled.value=isMetricsReportingEnabled(res.source.config);};const updateStorageStateFromLoadOptions=logger=>{const{useServerSideCookies,dataServiceEndpoint,storage:storageOptsFromLoad,setCookieDomain,sameDomainCookiesOnly}=state.loadOptions.value;let storageType=storageOptsFromLoad?.type;if(isDefined(storageType)&&!isValidStorageType(storageType)){logger?.warn(STORAGE_TYPE_VALIDATION_WARNING(CONFIG_MANAGER,storageType,DEFAULT_STORAGE_TYPE));storageType=DEFAULT_STORAGE_TYPE;}let storageEncryptionVersion=storageOptsFromLoad?.encryption?.version;const encryptionPluginName=storageEncryptionVersion&&StorageEncryptionVersionsToPluginNameMap[storageEncryptionVersion];if(!isUndefined(storageEncryptionVersion)&&isUndefined(encryptionPluginName)){// set the default encryption plugin
|
1086
|
+
*/const updateReportingState=res=>{state.reporting.isErrorReportingEnabled.value=isErrorReportingEnabled(res.source.config)&&!isSDKRunningInChromeExtension();state.reporting.isMetricsReportingEnabled.value=isMetricsReportingEnabled(res.source.config);};const updateStorageStateFromLoadOptions=logger=>{const{useServerSideCookies,dataServiceEndpoint,storage:storageOptsFromLoad,setCookieDomain,sameDomainCookiesOnly}=state.loadOptions.value;let storageType=storageOptsFromLoad?.type;if(isDefined(storageType)&&!isValidStorageType(storageType)){logger?.warn(STORAGE_TYPE_VALIDATION_WARNING(CONFIG_MANAGER,storageType,DEFAULT_STORAGE_TYPE));storageType=DEFAULT_STORAGE_TYPE;}let storageEncryptionVersion=storageOptsFromLoad?.encryption?.version;const encryptionPluginName=storageEncryptionVersion&&StorageEncryptionVersionsToPluginNameMap[storageEncryptionVersion];if(!isUndefined(storageEncryptionVersion)&&isUndefined(encryptionPluginName)){// set the default encryption plugin
|
1104
1087
|
logger?.warn(UNSUPPORTED_STORAGE_ENCRYPTION_VERSION_WARNING(CONFIG_MANAGER,storageEncryptionVersion,StorageEncryptionVersionsToPluginNameMap,DEFAULT_STORAGE_ENCRYPTION_VERSION));storageEncryptionVersion=DEFAULT_STORAGE_ENCRYPTION_VERSION;}else if(isUndefined(storageEncryptionVersion)){storageEncryptionVersion=DEFAULT_STORAGE_ENCRYPTION_VERSION;}// Allow migration only if the configured encryption version is the default encryption version
|
1105
1088
|
const configuredMigrationValue=storageOptsFromLoad?.migrate;const finalMigrationVal=configuredMigrationValue&&storageEncryptionVersion===DEFAULT_STORAGE_ENCRYPTION_VERSION;if(configuredMigrationValue===true&&finalMigrationVal!==configuredMigrationValue){logger?.warn(STORAGE_DATA_MIGRATION_OVERRIDE_WARNING(CONFIG_MANAGER,storageEncryptionVersion,DEFAULT_STORAGE_ENCRYPTION_VERSION));}r(()=>{state.storage.type.value=storageType;let cookieOptions=storageOptsFromLoad?.cookie??{};if(useServerSideCookies){state.serverCookies.isEnabledServerSideCookies.value=useServerSideCookies;const providedCookieDomain=cookieOptions.domain??setCookieDomain;/**
|
1106
1089
|
* Based on the following conditions, we decide whether to use the exact domain or not to determine the data service URL:
|