Skip to content

Commit c268646

Browse files
committed
refactor(reportingLogger): Replace LogRequest with IWSDKError and update severity handling; adjust tests for new error logging structure
1 parent 4de0bc7 commit c268646

File tree

3 files changed

+84
-86
lines changed

3 files changed

+84
-86
lines changed

src/logging/reportingLogger.ts

Lines changed: 33 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

22
import { ErrorCodes } from "./errorCodes";
3-
import { LogRequest, LogRequestSeverity } from "./logRequest";
3+
import { IWSDKError, WSDKErrorSeverity } from "./wsdk-error";
44
import { FetchUploader, XHRUploader } from "../uploaders";
55

66
export interface IReportingLogger {
@@ -13,52 +13,50 @@ export class ReportingLogger implements IReportingLogger {
1313
private readonly reporter: string = 'mp-wsdk';
1414
private readonly integration: string = 'mp-wsdk';
1515
private readonly rateLimiter: IRateLimiter;
16-
private readonly DEFAULT_ACCOUNT_ID: string = '0';
17-
private readonly DEFAULT_USER_AGENT: string = 'no-user-agent-set';
18-
private readonly DEFAULT_URL: string = 'no-url-set';
1916

2017
constructor(
2118
private baseUrl: string,
2219
private readonly sdkVersion: string,
2320
private readonly accountId: string,
21+
private readonly roktLauncherInstanceGuid: string,
2422
rateLimiter?: IRateLimiter,
2523
) {
2624
this.isEnabled = this.isReportingEnabled();
2725
this.rateLimiter = rateLimiter ?? new RateLimiter();
2826
}
2927

30-
public error(msg: string, code?: ErrorCodes, stackTrace?: string) {
31-
this.sendLog(LogRequestSeverity.Error, msg, code ?? ErrorCodes.UNHANDLED_EXCEPTION, stackTrace);
28+
public error(msg: string, code: ErrorCodes, stackTrace?: string) {
29+
this.sendLog(WSDKErrorSeverity.ERROR, msg, code, stackTrace);
3230
};
3331

34-
public warning(msg: string, code?: ErrorCodes) {
35-
this.sendLog(LogRequestSeverity.Warning, msg, code ?? ErrorCodes.UNHANDLED_EXCEPTION);
32+
public warning(msg: string, code: ErrorCodes) {
33+
this.sendLog(WSDKErrorSeverity.WARNING, msg, code);
3634
};
3735

3836
private sendLog(
39-
severity: LogRequestSeverity,
37+
severity: WSDKErrorSeverity,
4038
msg: string,
4139
code: ErrorCodes,
4240
stackTrace?: string
4341
): void {
4442
if(!this.canSendLog(severity))
4543
return;
4644

47-
const logRequest: LogRequest = {
45+
const wsdkError: IWSDKError = {
4846
additionalInformation: {
4947
message: msg,
5048
version: this.sdkVersion,
5149
},
5250
severity: severity,
5351
code: code,
54-
url: this.getUrl(),
55-
deviceInfo: this.getUserAgent(),
52+
url: window?.location?.href,
53+
deviceInfo: window?.navigator?.userAgent,
5654
stackTrace: stackTrace ?? '',
5755
reporter: this.reporter,
5856
integration: this.integration,
5957
};
6058

61-
this.sendLogToServer(logRequest);
59+
this.sendLogToServer(wsdkError);
6260
}
6361

6462
private isReportingEnabled(): boolean {
@@ -90,53 +88,51 @@ export class ReportingLogger implements IReportingLogger {
9088
);
9189
}
9290

93-
private canSendLog(severity: LogRequestSeverity): boolean {
91+
private canSendLog(severity: WSDKErrorSeverity): boolean {
9492
return this.isEnabled && !this.isRateLimited(severity);
9593
}
9694

97-
private isRateLimited(severity: LogRequestSeverity): boolean {
95+
private isRateLimited(severity: WSDKErrorSeverity): boolean {
9896
return this.rateLimiter.incrementAndCheck(severity);
9997
}
10098

101-
private getUrl(): string {
102-
return window?.location?.href ?? this.DEFAULT_URL;
103-
}
104-
105-
private getUserAgent(): string {
106-
return window?.navigator?.userAgent ?? this.DEFAULT_USER_AGENT;
107-
}
108-
109-
private sendLogToServer(logRequest: LogRequest) {
99+
private sendLogToServer(wsdkError: IWSDKError) {
110100
const uploadUrl = `${this.baseUrl}/v1/log`;
111101
const uploader = window.fetch
112102
? new FetchUploader(uploadUrl)
113103
: new XHRUploader(uploadUrl);
114104

105+
const headers = {
106+
Accept: 'text/plain;charset=UTF-8',
107+
'Content-Type': 'text/plain;charset=UTF-8',
108+
'rokt-launcher-instance-guid': this.roktLauncherInstanceGuid,
109+
};
110+
111+
if (this.accountId) {
112+
headers['rokt-account-id'] = this.accountId;
113+
}
114+
115115
uploader.upload({
116+
headers: headers,
116117
method: 'POST',
117-
headers: {
118-
Accept: 'text/plain;charset=UTF-8',
119-
'Content-Type': 'text/plain;charset=UTF-8',
120-
'rokt-account-id': this.accountId || this.DEFAULT_ACCOUNT_ID
121-
},
122-
body: JSON.stringify(logRequest),
118+
body: JSON.stringify(wsdkError),
123119
});
124120
};
125121
}
126122

127123
export interface IRateLimiter {
128-
incrementAndCheck(severity: LogRequestSeverity): boolean;
124+
incrementAndCheck(severity: WSDKErrorSeverity): boolean;
129125
}
130126

131127
export class RateLimiter implements IRateLimiter {
132-
private readonly rateLimits: Map<LogRequestSeverity, number> = new Map([
133-
[LogRequestSeverity.Error, 10],
134-
[LogRequestSeverity.Warning, 10],
135-
[LogRequestSeverity.Info, 10],
128+
private readonly rateLimits: Map<WSDKErrorSeverity, number> = new Map([
129+
[WSDKErrorSeverity.ERROR, 10],
130+
[WSDKErrorSeverity.WARNING, 10],
131+
[WSDKErrorSeverity.INFO, 10],
136132
]);
137-
private logCount: Map<LogRequestSeverity, number> = new Map();
133+
private logCount: Map<WSDKErrorSeverity, number> = new Map();
138134

139-
public incrementAndCheck(severity: LogRequestSeverity): boolean {
135+
public incrementAndCheck(severity: WSDKErrorSeverity): boolean {
140136
const count = this.logCount.get(severity) || 0;
141137
const limit = this.rateLimits.get(severity) || 10;
142138

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
import { ErrorCodes } from "./errorCodes";
22

3-
export enum LogRequestSeverity {
4-
Error = 'error',
5-
Warning = 'warning',
6-
Info = 'info',
7-
}
3+
export type WSDKErrorSeverity = (typeof WSDKErrorSeverity)[keyof typeof WSDKErrorSeverity];
4+
export const WSDKErrorSeverity = {
5+
ERROR: 'ERROR',
6+
INFO: 'INFO',
7+
WARNING: 'WARNING',
8+
} as const;
89

9-
export interface LogRequest {
10+
export interface IWSDKError {
1011
additionalInformation: {
1112
message: string;
1213
version: string;
1314
};
14-
severity: LogRequestSeverity;
15+
severity: WSDKErrorSeverity;
1516
code: ErrorCodes;
1617
url: string;
1718
deviceInfo: string;

test/jest/reportingLogger.spec.ts

Lines changed: 43 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { IRateLimiter, RateLimiter, ReportingLogger } from '../../src/logging/reportingLogger';
2-
import { LogRequestSeverity } from '../../src/logging/logRequest';
2+
import { WSDKErrorSeverity } from '../../src/logging/wsdk-error';
33
import { ErrorCodes } from '../../src/logging/errorCodes';
44

55
describe('ReportingLogger', () => {
@@ -8,6 +8,7 @@ describe('ReportingLogger', () => {
88
const sdkVersion = '1.2.3';
99
let mockFetch: jest.Mock;
1010
const accountId = '1234567890';
11+
const roktLauncherInstanceGuid = '1234567890';
1112
beforeEach(() => {
1213
mockFetch = jest.fn().mockResolvedValue({ ok: true });
1314
global.fetch = mockFetch;
@@ -24,7 +25,7 @@ describe('ReportingLogger', () => {
2425
ROKT_DOMAIN: 'set',
2526
fetch: mockFetch
2627
});
27-
logger = new ReportingLogger(baseUrl, sdkVersion, accountId);
28+
logger = new ReportingLogger(baseUrl, sdkVersion, accountId, roktLauncherInstanceGuid);
2829
});
2930

3031
afterEach(() => {
@@ -40,44 +41,55 @@ describe('ReportingLogger', () => {
4041
expect(fetchCall[0]).toContain('/v1/log');
4142
const body = JSON.parse(fetchCall[1].body);
4243
expect(body).toMatchObject({
43-
severity: LogRequestSeverity.Error,
44+
severity: WSDKErrorSeverity.ERROR,
4445
code: ErrorCodes.UNHANDLED_EXCEPTION,
45-
stackTrace: 'stack'
46+
});
47+
expect(fetchCall[1].headers).toMatchObject({
48+
'Accept': 'text/plain;charset=UTF-8',
49+
'Content-Type': 'text/plain;charset=UTF-8',
50+
'rokt-launcher-instance-guid': roktLauncherInstanceGuid,
51+
'rokt-account-id': accountId,
4652
});
4753
});
4854

4955
it('sends warning logs with correct params', () => {
50-
logger.warning('warn');
56+
logger.warning('warn', ErrorCodes.UNHANDLED_EXCEPTION);
5157
expect(mockFetch).toHaveBeenCalled();
5258
const fetchCall = mockFetch.mock.calls[0];
5359
expect(fetchCall[0]).toContain('/v1/log');
5460
const body = JSON.parse(fetchCall[1].body);
5561
expect(body).toMatchObject({
56-
severity: LogRequestSeverity.Warning
62+
severity: WSDKErrorSeverity.WARNING,
63+
code: ErrorCodes.UNHANDLED_EXCEPTION,
64+
});
65+
expect(fetchCall[1].headers).toMatchObject({
66+
'Accept': 'text/plain;charset=UTF-8',
67+
'Content-Type': 'text/plain;charset=UTF-8',
68+
'rokt-launcher-instance-guid': roktLauncherInstanceGuid,
69+
'rokt-account-id': accountId,
5770
});
58-
expect(fetchCall[1].headers['rokt-account-id']).toBe(accountId);
5971
});
6072

6173
it('does not log if ROKT_DOMAIN missing', () => {
6274
delete (globalThis as any).ROKT_DOMAIN;
63-
logger = new ReportingLogger(baseUrl, sdkVersion, accountId);
64-
logger.error('x');
75+
logger = new ReportingLogger(baseUrl, sdkVersion, accountId, roktLauncherInstanceGuid);
76+
logger.error('x', ErrorCodes.UNHANDLED_EXCEPTION);
6577
expect(mockFetch).not.toHaveBeenCalled();
6678
});
6779

6880
it('does not log if feature flag and debug mode off', () => {
6981
window.mParticle.config.isWebSdkLoggingEnabled = false;
7082
window.location.search = '';
71-
logger = new ReportingLogger(baseUrl, sdkVersion, accountId);
72-
logger.error('x');
83+
logger = new ReportingLogger(baseUrl, sdkVersion, accountId, roktLauncherInstanceGuid);
84+
logger.error('x', ErrorCodes.UNHANDLED_EXCEPTION);
7385
expect(mockFetch).not.toHaveBeenCalled();
7486
});
7587

7688
it('logs if debug mode on even if feature flag off', () => {
7789
window.mParticle.config.isWebSdkLoggingEnabled = false;
7890
window.location.search = '?mp_enable_logging=true';
79-
logger = new ReportingLogger(baseUrl, sdkVersion, accountId);
80-
logger.error('x');
91+
logger = new ReportingLogger(baseUrl, sdkVersion, accountId, roktLauncherInstanceGuid);
92+
logger.error('x', ErrorCodes.UNHANDLED_EXCEPTION);
8193
expect(mockFetch).toHaveBeenCalled();
8294
});
8395

@@ -88,29 +100,18 @@ describe('ReportingLogger', () => {
88100
return ++count > 3;
89101
}),
90102
};
91-
logger = new ReportingLogger(baseUrl, sdkVersion, accountId, mockRateLimiter);
103+
logger = new ReportingLogger(baseUrl, sdkVersion, accountId, roktLauncherInstanceGuid, mockRateLimiter);
92104

93-
for (let i = 0; i < 5; i++) logger.error('err');
105+
for (let i = 0; i < 5; i++) logger.error('err', ErrorCodes.UNHANDLED_EXCEPTION);
94106
expect(mockFetch).toHaveBeenCalledTimes(3);
95107
});
96108

97-
it('uses default account id when accountId is empty', () => {
98-
logger = new ReportingLogger(baseUrl, sdkVersion, undefined);
99-
logger.error('msg');
109+
it('does not send account id when accountId is empty', () => {
110+
logger = new ReportingLogger(baseUrl, sdkVersion, '', roktLauncherInstanceGuid);
111+
logger.error('msg', ErrorCodes.UNHANDLED_EXCEPTION);
100112
expect(mockFetch).toHaveBeenCalled();
101113
const fetchCall = mockFetch.mock.calls[0];
102-
expect(fetchCall[1].headers['rokt-account-id']).toBe('0');
103-
});
104-
105-
it('uses default user agent when user agent is empty', () => {
106-
logger = new ReportingLogger(baseUrl, sdkVersion, accountId);
107-
delete (globalThis as any).navigator;
108-
delete (globalThis as any).location;
109-
logger.error('msg');
110-
expect(mockFetch).toHaveBeenCalled();
111-
const fetchCall = mockFetch.mock.calls[0];
112-
const body = JSON.parse(fetchCall[1].body);
113-
expect(body).toMatchObject({ deviceInfo: 'no-user-agent-set', url: 'no-url-set' });
114+
expect(fetchCall[1].headers['rokt-account-id']).toBeUndefined();
114115
});
115116
});
116117

@@ -122,33 +123,33 @@ describe('RateLimiter', () => {
122123

123124
it('allows up to 10 error logs then rate limits', () => {
124125
for (let i = 0; i < 10; i++) {
125-
expect(rateLimiter.incrementAndCheck(LogRequestSeverity.Error)).toBe(false);
126+
expect(rateLimiter.incrementAndCheck(WSDKErrorSeverity.ERROR)).toBe(false);
126127
}
127-
expect(rateLimiter.incrementAndCheck(LogRequestSeverity.Error)).toBe(true);
128-
expect(rateLimiter.incrementAndCheck(LogRequestSeverity.Error)).toBe(true);
128+
expect(rateLimiter.incrementAndCheck(WSDKErrorSeverity.ERROR)).toBe(true);
129+
expect(rateLimiter.incrementAndCheck(WSDKErrorSeverity.ERROR)).toBe(true);
129130
});
130131

131132
it('allows up to 10 warning logs then rate limits', () => {
132133
for (let i = 0; i < 10; i++) {
133-
expect(rateLimiter.incrementAndCheck(LogRequestSeverity.Warning)).toBe(false);
134+
expect(rateLimiter.incrementAndCheck(WSDKErrorSeverity.WARNING)).toBe(false);
134135
}
135-
expect(rateLimiter.incrementAndCheck(LogRequestSeverity.Warning)).toBe(true);
136-
expect(rateLimiter.incrementAndCheck(LogRequestSeverity.Warning)).toBe(true);
136+
expect(rateLimiter.incrementAndCheck(WSDKErrorSeverity.WARNING)).toBe(true);
137+
expect(rateLimiter.incrementAndCheck(WSDKErrorSeverity.WARNING)).toBe(true);
137138
});
138139

139140
it('allows up to 10 info logs then rate limits', () => {
140141
for (let i = 0; i < 10; i++) {
141-
expect(rateLimiter.incrementAndCheck(LogRequestSeverity.Info)).toBe(false);
142+
expect(rateLimiter.incrementAndCheck(WSDKErrorSeverity.INFO)).toBe(false);
142143
}
143-
expect(rateLimiter.incrementAndCheck(LogRequestSeverity.Info)).toBe(true);
144-
expect(rateLimiter.incrementAndCheck(LogRequestSeverity.Info)).toBe(true);
144+
expect(rateLimiter.incrementAndCheck(WSDKErrorSeverity.INFO)).toBe(true);
145+
expect(rateLimiter.incrementAndCheck(WSDKErrorSeverity.INFO)).toBe(true);
145146
});
146147

147148
it('tracks rate limits independently per severity', () => {
148149
for (let i = 0; i < 10; i++) {
149-
rateLimiter.incrementAndCheck(LogRequestSeverity.Error);
150+
rateLimiter.incrementAndCheck(WSDKErrorSeverity.ERROR);
150151
}
151-
expect(rateLimiter.incrementAndCheck(LogRequestSeverity.Error)).toBe(true);
152-
expect(rateLimiter.incrementAndCheck(LogRequestSeverity.Warning)).toBe(false);
152+
expect(rateLimiter.incrementAndCheck(WSDKErrorSeverity.ERROR)).toBe(true);
153+
expect(rateLimiter.incrementAndCheck(WSDKErrorSeverity.WARNING)).toBe(false);
153154
});
154155
});

0 commit comments

Comments
 (0)