Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,6 @@ const Constants = {
identityUrl: 'identity.mparticle.com/v1/',
aliasUrl: 'jssdks.mparticle.com/v1/identity/',
userAudienceUrl: 'nativesdks.mparticle.com/v1/',
loggingUrl: 'apps.rokt-api.com/v1/log',
errorUrl: 'apps.rokt-api.com/v1/errors',
},
// These are the paths that are used to construct the CNAME urls
CNAMEUrlPaths: {
Expand All @@ -150,8 +148,6 @@ const Constants = {
configUrl: '/tags/JS/v2/',
identityUrl: '/identity/v1/',
aliasUrl: '/webevents/v1/identity/',
loggingUrl: '/v1/log',
errorUrl: '/v1/errors',
},
Base64CookieKeys: {
csm: 1,
Expand Down
13 changes: 8 additions & 5 deletions src/identityApiClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import {
IIdentityResponse,
} from './identity-user-interfaces';
import { IMParticleWebSDKInstance } from './mp-instance';
import { ErrorCodes } from './logging/types';
import { ErrorCodes, WSDKErrorSeverity } from './reporting/types';

const { HTTPCodes, Messages, IdentityMethods } = Constants;

Expand Down Expand Up @@ -329,10 +329,13 @@ export default function IdentityAPIClient(
}

const errorMessage = (err as Error).message || err.toString();
Logger.error(
'Error sending identity request to servers' + ' - ' + errorMessage,
ErrorCodes.IDENTITY_REQUEST
);
const msg = 'Error sending identity request to servers' + ' - ' + errorMessage;
Logger.error(msg);
mpInstance._ErrorReportingDispatcher?.report({
message: msg,
code: ErrorCodes.IDENTITY_REQUEST,
severity: WSDKErrorSeverity.ERROR,
});

mpInstance.processQueueOnIdentityFailure?.();
invokeCallback(callback, HTTPCodes.noHttpCoverage, errorMessage);
Expand Down
15 changes: 3 additions & 12 deletions src/logger.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,19 @@
import { LogLevelType, SDKInitConfig, SDKLoggerApi } from './sdkRuntimeModels';
import { ReportingLogger } from './logging/reportingLogger';
import { ErrorCodes } from './logging/types';

export type ILoggerConfig = Pick<SDKInitConfig, 'logLevel' | 'logger'>;
export type IConsoleLogger = Partial<Pick<SDKLoggerApi, 'error' | 'warning' | 'verbose'>>;

export class Logger {
private logLevel: LogLevelType;
private logger: IConsoleLogger;
private reportingLogger: ReportingLogger;

constructor(config: ILoggerConfig,
reportingLogger?: ReportingLogger,
) {
constructor(config: ILoggerConfig) {
this.logLevel = config.logLevel ?? LogLevelType.Warning;
this.logger = config.logger ?? new ConsoleLogger();
this.reportingLogger = reportingLogger;
}

public verbose(msg: string): void {
if(this.logLevel === LogLevelType.None)
if(this.logLevel === LogLevelType.None)
return;

if (this.logger.verbose && this.logLevel === LogLevelType.Verbose) {
Expand All @@ -37,15 +31,12 @@ export class Logger {
}
}

public error(msg: string, codeForReporting?: ErrorCodes): void {
public error(msg: string): void {
if(this.logLevel === LogLevelType.None)
return;

if (this.logger.error) {
this.logger.error(msg);
if (codeForReporting) {
this.reportingLogger?.error(msg, codeForReporting);
}
}
}

Expand Down
192 changes: 0 additions & 192 deletions src/logging/reportingLogger.ts

This file was deleted.

34 changes: 20 additions & 14 deletions src/mp-instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ import ForegroundTimer from './foregroundTimeTracker';
import RoktManager, { IRoktOptions } from './roktManager';
import filteredMparticleUser from './filteredMparticleUser';
import CookieConsentManager, { ICookieConsentManager } from './cookieConsentManager';
import { ReportingLogger } from './logging/reportingLogger';
import { ErrorReportingDispatcher } from './reporting/errorReportingDispatcher';
import { LoggingDispatcher } from './reporting/loggingDispatcher';
import { IErrorReportingService, ILoggingService } from './reporting/types';

export interface IErrorLogMessage {
message?: string;
Expand Down Expand Up @@ -85,7 +87,8 @@ export interface IMParticleWebSDKInstance extends MParticleWebSDK {
_NativeSdkHelpers: INativeSdkHelpers;
_Persistence: IPersistence;
_CookieConsentManager: ICookieConsentManager;
_ReportingLogger: ReportingLogger;
_ErrorReportingDispatcher: ErrorReportingDispatcher;
_LoggingDispatcher: LoggingDispatcher;
_RoktManager: RoktManager;
_SessionManager: ISessionManager;
_ServerModel: IServerModel;
Expand Down Expand Up @@ -266,14 +269,14 @@ export default function mParticleInstance(this: IMParticleWebSDKInstance, instan
}
};

this._resetForTests = function(config, keepPersistence, instance, reportingLogger?: ReportingLogger) {
this._resetForTests = function(config, keepPersistence, instance) {
if (instance._Store) {
delete instance._Store;
}
instance.Logger = new Logger(config, reportingLogger);
instance._ErrorReportingDispatcher = new ErrorReportingDispatcher();
instance._LoggingDispatcher = new LoggingDispatcher();
instance.Logger = new Logger(config);
instance._Store = new Store(config, instance);
// Update ReportingLogger with the new Store reference to avoid stale data
reportingLogger?.setStore(instance._Store);
instance._Store.isLocalStorageAvailable = instance._Persistence.determineLocalStorageAvailability(
window.localStorage
);
Expand Down Expand Up @@ -1406,6 +1409,14 @@ export default function mParticleInstance(this: IMParticleWebSDKInstance, instan
}
};

this.registerErrorReportingService = function(service: IErrorReportingService) {
self._ErrorReportingDispatcher.register(service);
};

this.registerLoggingService = function(service: ILoggingService) {
self._LoggingDispatcher.register(service);
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Register methods crash when called before init

High Severity

registerErrorReportingService and registerLoggingService access self._ErrorReportingDispatcher and self._LoggingDispatcher directly without null guards, but these dispatchers are only created inside runPreConfigFetchInitialization (called during init()). Calling either registration method before init() throws a TypeError. Other public API methods in this file (e.g., setAppVersion, _setWrapperSDKInfo) use queueIfNotInitialized to handle this scenario, but the new methods do not.

Additional Locations (1)
Fix in Cursor Fix in Web


const launcherInstanceGuidKey = Constants.Rokt.LauncherInstanceGuidKey;
this.setLauncherInstanceGuid = function() {
if (!window[launcherInstanceGuidKey]
Expand Down Expand Up @@ -1630,16 +1641,11 @@ function createIdentityCache(mpInstance) {
}

function runPreConfigFetchInitialization(mpInstance, apiKey, config) {
mpInstance._ReportingLogger = new ReportingLogger(
config,
Constants.sdkVersion,
undefined,
mpInstance.getLauncherInstanceGuid(),
);
mpInstance.Logger = new Logger(config, mpInstance._ReportingLogger);
mpInstance._ErrorReportingDispatcher = new ErrorReportingDispatcher();
mpInstance._LoggingDispatcher = new LoggingDispatcher();
mpInstance.Logger = new Logger(config);
mpInstance._Store = new Store(config, mpInstance, apiKey);
window.mParticle.Store = mpInstance._Store;
mpInstance._ReportingLogger.setStore(mpInstance._Store);
mpInstance.Logger.verbose(StartingInitialization);

// Initialize CookieConsentManager with privacy flags from launcherOptions
Expand Down
6 changes: 6 additions & 0 deletions src/mparticle-instance-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,12 @@ function mParticleInstanceManager(this: IMParticleInstanceManager) {
this._setWrapperSDKInfo = function(name, version) {
self.getInstance()._setWrapperSDKInfo(name, version);
};
this.registerErrorReportingService = function(service) {
self.getInstance().registerErrorReportingService(service);
};
this.registerLoggingService = function(service) {
self.getInstance().registerLoggingService(service);
};
}

const mParticleManager = new mParticleInstanceManager();
Expand Down
13 changes: 13 additions & 0 deletions src/reporting/errorReportingDispatcher.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { IErrorReportingService, ISDKError } from './types';

export class ErrorReportingDispatcher implements IErrorReportingService {
private services: IErrorReportingService[] = [];

Check warning on line 4 in src/reporting/errorReportingDispatcher.ts

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Member 'services' is never reassigned; mark it as `readonly`.

See more on https://sonarcloud.io/project/issues?id=mParticle_mparticle-web-sdk&issues=AZ0M_9fCNfgQaKDpvnIQ&open=AZ0M_9fCNfgQaKDpvnIQ&pullRequest=1224

public register(service: IErrorReportingService): void {
this.services.push(service);
}

public report(error: ISDKError): void {
this.services.forEach(s => s.report(error));
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dispatcher fan-out lacks error isolation between services

Medium Severity

ErrorReportingDispatcher.report() and LoggingDispatcher.log() iterate over registered services via forEach without any try-catch. If any externally registered service throws, subsequent services are skipped and the exception propagates to the caller. In identityApiClient.ts, report() is called inside a catch block before critical operations like processQueueOnIdentityFailure and invokeCallback — a throwing service would cause those to be silently skipped. The removed ReportingLogger had internal try-catch preventing this.

Additional Locations (2)
Fix in Cursor Fix in Web

}
13 changes: 13 additions & 0 deletions src/reporting/loggingDispatcher.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { ILoggingService, ISDKLogEntry } from './types';

export class LoggingDispatcher implements ILoggingService {
private services: ILoggingService[] = [];

Check warning on line 4 in src/reporting/loggingDispatcher.ts

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Member 'services' is never reassigned; mark it as `readonly`.

See more on https://sonarcloud.io/project/issues?id=mParticle_mparticle-web-sdk&issues=AZ0M_9h7NfgQaKDpvnIS&open=AZ0M_9h7NfgQaKDpvnIS&pullRequest=1224

public register(service: ILoggingService): void {
this.services.push(service);
}

public log(entry: ISDKLogEntry): void {
this.services.forEach(s => s.log(entry));
}
}
Loading
Loading