@posiwise/common-services 0.1.40 → 0.1.41
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/esm2022/lib/ab-test.service.mjs +1 -1
- package/esm2022/lib/ahoy.service.mjs +1 -1
- package/esm2022/lib/auth.service.mjs +1 -1
- package/esm2022/lib/base-http.service.mjs +2 -2
- package/esm2022/lib/common-services.interface.mjs +1 -1
- package/esm2022/lib/common.service.mjs +1 -1
- package/esm2022/lib/custom-preloading.service.mjs +1 -1
- package/esm2022/lib/dashboard.service.mjs +1 -1
- package/esm2022/lib/data.service.mjs +1 -1
- package/esm2022/lib/date-formatter.service.mjs +9 -4
- package/esm2022/lib/effects/user.effects.mjs +1 -1
- package/esm2022/lib/geo.service.mjs +1 -1
- package/esm2022/lib/google-analytics.service.mjs +13 -9
- package/esm2022/lib/group.service.mjs +1 -1
- package/esm2022/lib/hopscotch.service.mjs +1 -1
- package/esm2022/lib/link-loader.service.mjs +1 -1
- package/esm2022/lib/mailbox.service.mjs +1 -1
- package/esm2022/lib/notification.service.mjs +1 -1
- package/esm2022/lib/permission.service.mjs +4 -4
- package/esm2022/lib/product.service.mjs +1 -1
- package/esm2022/lib/profile.service.mjs +1 -1
- package/esm2022/lib/qualification.service.mjs +1 -1
- package/esm2022/lib/script-loader.service.mjs +5 -4
- package/esm2022/lib/sentry.service.mjs +127 -108
- package/esm2022/lib/socket.service.mjs +1 -1
- package/esm2022/lib/subscription.service.mjs +4 -4
- package/esm2022/lib/tag.service.mjs +1 -1
- package/esm2022/lib/tips.service.mjs +1 -1
- package/esm2022/lib/toast.service.mjs +1 -1
- package/esm2022/lib/user.service.mjs +1 -1
- package/esm2022/lib/validation.service.mjs +2 -2
- package/fesm2022/posiwise-common-services.mjs +158 -129
- package/fesm2022/posiwise-common-services.mjs.map +1 -1
- package/lib/ab-test.service.d.ts +1 -1
- package/lib/ahoy.service.d.ts +3 -3
- package/lib/auth.service.d.ts +10 -10
- package/lib/base-http.service.d.ts +1 -1
- package/lib/common-services.interface.d.ts +2 -3
- package/lib/common.service.d.ts +1 -1
- package/lib/custom-preloading.service.d.ts +1 -1
- package/lib/dashboard.service.d.ts +1 -1
- package/lib/data.service.d.ts +1 -1
- package/lib/effects/user.effects.d.ts +2 -2
- package/lib/geo.service.d.ts +3 -3
- package/lib/google-analytics.service.d.ts +4 -3
- package/lib/group.service.d.ts +5 -5
- package/lib/hopscotch.service.d.ts +3 -3
- package/lib/link-loader.service.d.ts +2 -2
- package/lib/mailbox.service.d.ts +3 -3
- package/lib/notification.service.d.ts +4 -4
- package/lib/permission.service.d.ts +1 -1
- package/lib/product.service.d.ts +2 -2
- package/lib/profile.service.d.ts +4 -4
- package/lib/qualification.service.d.ts +2 -2
- package/lib/script-loader.service.d.ts +1 -1
- package/lib/sentry.service.d.ts +9 -1
- package/lib/socket.service.d.ts +2 -2
- package/lib/subscription.service.d.ts +1 -1
- package/lib/tag.service.d.ts +1 -1
- package/lib/tips.service.d.ts +1 -1
- package/lib/toast.service.d.ts +1 -1
- package/lib/user.service.d.ts +4 -4
- package/lib/validation.service.d.ts +1 -1
- package/package.json +1 -1
|
@@ -33,7 +33,7 @@ import { fromError } from 'stacktrace-js';
|
|
|
33
33
|
class ScriptLoaderService {
|
|
34
34
|
constructor(document) {
|
|
35
35
|
this.document = document;
|
|
36
|
-
this._scripts =
|
|
36
|
+
this._scripts = {};
|
|
37
37
|
}
|
|
38
38
|
load(tag, ...scripts) {
|
|
39
39
|
scripts.forEach((src) => {
|
|
@@ -57,13 +57,14 @@ class ScriptLoaderService {
|
|
|
57
57
|
return Promise.all(promises);
|
|
58
58
|
}
|
|
59
59
|
loadScript(tag, src, loadOnce) {
|
|
60
|
-
|
|
60
|
+
const isLoad = loadOnce || false;
|
|
61
61
|
if (!this._scripts[src]) {
|
|
62
62
|
this._scripts[src] = { src, loaded: false };
|
|
63
63
|
}
|
|
64
64
|
return new Promise((resolve, _reject) => {
|
|
65
65
|
// resolve if already loaded
|
|
66
|
-
if (this._scripts[src].loaded &&
|
|
66
|
+
if (this._scripts[src].loaded && isLoad) {
|
|
67
|
+
// NOSONAR
|
|
67
68
|
resolve({ src, loaded: true });
|
|
68
69
|
}
|
|
69
70
|
else {
|
|
@@ -124,13 +125,7 @@ class GoogleAnalyticsService {
|
|
|
124
125
|
this.scriptLoader
|
|
125
126
|
.loadScript('head', 'https://www.google-analytics.com/analytics.js', true)
|
|
126
127
|
.then(() => {
|
|
127
|
-
|
|
128
|
-
ga ||
|
|
129
|
-
// eslint-disable-next-line func-names
|
|
130
|
-
function () {
|
|
131
|
-
// eslint-disable-next-line prefer-rest-params
|
|
132
|
-
(ga.q = ga.q || []).push(arguments);
|
|
133
|
-
};
|
|
128
|
+
this.pushArgumentsGA();
|
|
134
129
|
ga.l = Date.now();
|
|
135
130
|
GoogleAnalyticsService.trackingId = config.integrations.google_analytics;
|
|
136
131
|
ga('create', GoogleAnalyticsService.trackingId, 'auto');
|
|
@@ -138,11 +133,21 @@ class GoogleAnalyticsService {
|
|
|
138
133
|
})
|
|
139
134
|
.catch(error => {
|
|
140
135
|
console.error('Error loading Google Analytics script:', error);
|
|
141
|
-
reject(error);
|
|
136
|
+
reject(error instanceof Error ? error : new Error(error));
|
|
142
137
|
});
|
|
143
138
|
});
|
|
144
139
|
});
|
|
145
140
|
}
|
|
141
|
+
pushArgumentsGA() {
|
|
142
|
+
ga =
|
|
143
|
+
ga ||
|
|
144
|
+
// eslint-disable-next-line func-names
|
|
145
|
+
function () {
|
|
146
|
+
ga.q = ga.q = ga.q || [];
|
|
147
|
+
// eslint-disable-next-line prefer-rest-params
|
|
148
|
+
ga.q.push(arguments);
|
|
149
|
+
};
|
|
150
|
+
}
|
|
146
151
|
subscribe() {
|
|
147
152
|
if (!this.subscription) {
|
|
148
153
|
this.subscription = this.router.events.subscribe(e => {
|
|
@@ -354,7 +359,7 @@ class BaseHttpService {
|
|
|
354
359
|
const formData = new FormData();
|
|
355
360
|
// eslint-disable-next-line no-restricted-syntax
|
|
356
361
|
for (const item in data) {
|
|
357
|
-
if (Object.
|
|
362
|
+
if (Object.hasOwn(data, item)) {
|
|
358
363
|
formData.append(item, data[item]);
|
|
359
364
|
}
|
|
360
365
|
}
|
|
@@ -874,7 +879,7 @@ class PermissionService {
|
|
|
874
879
|
// Returning true if user has a given permission
|
|
875
880
|
// E.g., Pages.Role.CloudOlive.SalesManager
|
|
876
881
|
// or Pages.Beta or Pages.Alpha
|
|
877
|
-
if (user['auth']
|
|
882
|
+
if (user['auth']?.['granted'][permissionName]) {
|
|
878
883
|
return true;
|
|
879
884
|
}
|
|
880
885
|
if (productKey) {
|
|
@@ -934,7 +939,6 @@ class PermissionService {
|
|
|
934
939
|
return this.isUserSubscriptionOwner();
|
|
935
940
|
}
|
|
936
941
|
if (permission === PERMISSION_NAMES.SubscriptionSuperAdmin) {
|
|
937
|
-
// SubscriptionAdmin: Product SuperAdmin
|
|
938
942
|
return (this.isUserSubscriptionSuperAdmin() ||
|
|
939
943
|
this.isUserSubscriptionSuperOwner() ||
|
|
940
944
|
this.isSuperAdmin());
|
|
@@ -961,7 +965,8 @@ class PermissionService {
|
|
|
961
965
|
expr += `${raw} `;
|
|
962
966
|
}, this);
|
|
963
967
|
// eslint-disable-next-line no-eval
|
|
964
|
-
|
|
968
|
+
// NOSONAR: Trusted eval function is handled safely here
|
|
969
|
+
return eval(expr); // NOSONAR
|
|
965
970
|
}
|
|
966
971
|
getPermissionByRole(roleId) {
|
|
967
972
|
return this.api.get(`/admin/role_permissions/${roleId}`);
|
|
@@ -1263,7 +1268,7 @@ class SubscriptionService {
|
|
|
1263
1268
|
const formData = new FormData();
|
|
1264
1269
|
// eslint-disable-next-line no-restricted-syntax
|
|
1265
1270
|
for (const key in data) {
|
|
1266
|
-
if (Object.
|
|
1271
|
+
if (Object.hasOwn(data, key)) {
|
|
1267
1272
|
formData.append(key, data[key]);
|
|
1268
1273
|
}
|
|
1269
1274
|
}
|
|
@@ -1279,7 +1284,7 @@ class SubscriptionService {
|
|
|
1279
1284
|
const formData = new FormData();
|
|
1280
1285
|
// eslint-disable-next-line no-restricted-syntax
|
|
1281
1286
|
for (const key in data) {
|
|
1282
|
-
if (Object.
|
|
1287
|
+
if (Object.hasOwn(data, key)) {
|
|
1283
1288
|
formData.append(key, data[key]);
|
|
1284
1289
|
}
|
|
1285
1290
|
}
|
|
@@ -1289,7 +1294,7 @@ class SubscriptionService {
|
|
|
1289
1294
|
const formData = new FormData();
|
|
1290
1295
|
// eslint-disable-next-line no-restricted-syntax
|
|
1291
1296
|
for (const key in data) {
|
|
1292
|
-
if (Object.
|
|
1297
|
+
if (Object.hasOwn(data, key)) {
|
|
1293
1298
|
formData.append(key, data[key]);
|
|
1294
1299
|
}
|
|
1295
1300
|
}
|
|
@@ -1425,7 +1430,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImpo
|
|
|
1425
1430
|
|
|
1426
1431
|
class ValidationService {
|
|
1427
1432
|
static { this.CustomValidatorPatterns = {
|
|
1428
|
-
StrongPassword: /^(?=.*[a-z])(?=.*[A-Z])(
|
|
1433
|
+
StrongPassword: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*])(?=.{8,})/,
|
|
1429
1434
|
Year: '[0-9]{4}$'
|
|
1430
1435
|
}; }
|
|
1431
1436
|
/**
|
|
@@ -1748,9 +1753,14 @@ class NgbDateCustomParserFormatter extends NgbDateParserFormatter {
|
|
|
1748
1753
|
'Nov',
|
|
1749
1754
|
'Dec'
|
|
1750
1755
|
];
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1756
|
+
if (!date) {
|
|
1757
|
+
return '';
|
|
1758
|
+
}
|
|
1759
|
+
const day = isNumber(date.day) ? padNumber(date.day) : '';
|
|
1760
|
+
const month = isNumber(date.month) ? monthNames[date.month] : '';
|
|
1761
|
+
const year = date.year;
|
|
1762
|
+
console.log("In thi");
|
|
1763
|
+
return `${day}-${month}-${year}`;
|
|
1754
1764
|
}
|
|
1755
1765
|
dateFormatForPicker(date) {
|
|
1756
1766
|
return {
|
|
@@ -2306,13 +2316,13 @@ class SentryErrorHandler {
|
|
|
2306
2316
|
tracesSampleRate: 0.1,
|
|
2307
2317
|
beforeSend(event, hint) {
|
|
2308
2318
|
// Check if the event is of type CloseEvent and ignore it
|
|
2309
|
-
if (event
|
|
2319
|
+
if (event?.exception?.values) {
|
|
2310
2320
|
event.exception.values = event.exception.values.filter(value => {
|
|
2311
2321
|
// Update the condition based on the actual structure of the event
|
|
2312
2322
|
return !(value.type === 'CloseEvent' || value.value.includes('CloseEvent'));
|
|
2313
2323
|
});
|
|
2314
2324
|
}
|
|
2315
|
-
if (event
|
|
2325
|
+
if (event?.exception?.values) {
|
|
2316
2326
|
event.exception.values = event.exception.values.filter(value => {
|
|
2317
2327
|
// Check for the specific error message and ignore it
|
|
2318
2328
|
return !(value.type === 'Error' &&
|
|
@@ -2320,43 +2330,41 @@ class SentryErrorHandler {
|
|
|
2320
2330
|
});
|
|
2321
2331
|
}
|
|
2322
2332
|
// originates from vendor.js file
|
|
2323
|
-
if (event
|
|
2333
|
+
if (event?.exception?.values) {
|
|
2324
2334
|
const isJsonParsingError = event.exception.values.some(value => {
|
|
2325
2335
|
return (value.type === 'SyntaxError' &&
|
|
2326
|
-
value
|
|
2327
|
-
value.value.includes("expected ':' after property name in"));
|
|
2336
|
+
value?.value?.includes("expected ':' after property name in"));
|
|
2328
2337
|
});
|
|
2329
2338
|
if (isJsonParsingError) {
|
|
2330
2339
|
return null;
|
|
2331
2340
|
}
|
|
2332
2341
|
}
|
|
2333
2342
|
// Check if the event is a ChunkLoadError and ignore it (it could be because of poor network)
|
|
2334
|
-
if (event
|
|
2343
|
+
if (event?.exception?.values) {
|
|
2335
2344
|
event.exception.values = event.exception.values.filter(value => {
|
|
2336
2345
|
return !(value.type === 'ChunkLoadError' ||
|
|
2337
2346
|
value.value.includes('ChunkLoadError: Loading chunk'));
|
|
2338
2347
|
});
|
|
2339
2348
|
}
|
|
2340
2349
|
// Check if the event is a script loading error and ignore it
|
|
2341
|
-
if (event
|
|
2350
|
+
if (event?.exception?.values) {
|
|
2342
2351
|
event.exception.values = event.exception.values.filter(value => {
|
|
2343
2352
|
return !(value.type === 'Error' &&
|
|
2344
2353
|
value.value.includes('Could not load "util"'));
|
|
2345
2354
|
});
|
|
2346
2355
|
}
|
|
2347
2356
|
// Check if the event is a timeout error and ignore it
|
|
2348
|
-
if (event
|
|
2357
|
+
if (event?.exception?.values) {
|
|
2349
2358
|
event.exception.values = event.exception.values.filter(value => {
|
|
2350
2359
|
return !(value.type === 'Error' &&
|
|
2351
2360
|
value.value.includes('Error loading plotly.js library from'));
|
|
2352
2361
|
});
|
|
2353
2362
|
}
|
|
2354
2363
|
// Check if the event is related to cross-origin frame access
|
|
2355
|
-
if (event
|
|
2364
|
+
if (event?.exception?.values) {
|
|
2356
2365
|
const isCrossOriginFrameError = event.exception.values.some(value => {
|
|
2357
2366
|
return (value.type === 'SecurityError' &&
|
|
2358
|
-
value
|
|
2359
|
-
value.value.includes("Failed to read a named property 'navigator' from 'Window': Blocked a frame with origin"));
|
|
2367
|
+
value?.value?.includes("Failed to read a named property 'navigator' from 'Window': Blocked a frame with origin"));
|
|
2360
2368
|
});
|
|
2361
2369
|
if (isCrossOriginFrameError) {
|
|
2362
2370
|
// Exclude cross-origin frame errors from being reported to Sentry
|
|
@@ -2364,7 +2372,7 @@ class SentryErrorHandler {
|
|
|
2364
2372
|
}
|
|
2365
2373
|
}
|
|
2366
2374
|
// Check if the event has an exception and values array
|
|
2367
|
-
if (event
|
|
2375
|
+
if (event?.exception?.values) {
|
|
2368
2376
|
// Filter out events generated by TryCatch and GlobalHandlers
|
|
2369
2377
|
event.exception.values = event.exception.values.filter(value => {
|
|
2370
2378
|
const mechanism = value.mechanism;
|
|
@@ -2459,125 +2467,146 @@ class SentryErrorHandler {
|
|
|
2459
2467
|
return;
|
|
2460
2468
|
}
|
|
2461
2469
|
}
|
|
2470
|
+
this.handleExceptionError(incomingError);
|
|
2471
|
+
}
|
|
2472
|
+
handleExceptionError(incomingError) {
|
|
2462
2473
|
if (incomingError) {
|
|
2463
2474
|
let error = incomingError; // The actual error to log
|
|
2464
2475
|
while ('originalError' in error && error.originalError instanceof Error) {
|
|
2465
2476
|
this.logToConsole(error);
|
|
2466
2477
|
error = error.originalError;
|
|
2467
2478
|
}
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
return; // Don't rethrow the error
|
|
2478
|
-
}
|
|
2479
|
-
let { message } = error;
|
|
2480
|
-
if (!message) {
|
|
2481
|
-
try {
|
|
2482
|
-
message = JSON.stringify(error);
|
|
2483
|
-
}
|
|
2484
|
-
catch (e) {
|
|
2485
|
-
message = error.toString();
|
|
2486
|
-
console.log(e);
|
|
2487
|
-
}
|
|
2488
|
-
}
|
|
2489
|
-
error = new Error(`Got HttpErrorResponse on URL ${error.url} message: ${message}`);
|
|
2479
|
+
this.extractOriginalError(error, incomingError);
|
|
2480
|
+
}
|
|
2481
|
+
}
|
|
2482
|
+
extractOriginalError(error, incomingError) {
|
|
2483
|
+
// Exclude specific errors
|
|
2484
|
+
if (error instanceof HttpErrorResponse) {
|
|
2485
|
+
if (error.status === StatusCodes.NOT_FOUND) {
|
|
2486
|
+
console.warn('Excluded 404 error:', error);
|
|
2487
|
+
return; // Skip logging to Sentry
|
|
2490
2488
|
}
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2489
|
+
if (error.status === 0 && error.statusText === 'Unknown Error') {
|
|
2490
|
+
// Handle network-related errors differently or suppress them
|
|
2491
|
+
console.warn('Network-related error:', error);
|
|
2492
|
+
return; // Don't rethrow the error
|
|
2493
|
+
}
|
|
2494
|
+
let { message } = error;
|
|
2495
|
+
if (!message) {
|
|
2496
|
+
try {
|
|
2497
|
+
message = JSON.stringify(error);
|
|
2498
|
+
}
|
|
2499
|
+
catch (e) {
|
|
2500
|
+
message = error.toString();
|
|
2501
|
+
console.log(e);
|
|
2497
2502
|
}
|
|
2498
|
-
// Exclude reporting 401 errors
|
|
2499
2503
|
}
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2504
|
+
error = new Error(`Got HttpErrorResponse on URL ${error.url} message: ${message}`);
|
|
2505
|
+
}
|
|
2506
|
+
this.handleNonHttpErrorResponse(error);
|
|
2507
|
+
// Ensure all errors have a proper message
|
|
2508
|
+
this.errorMessageFormatter(error);
|
|
2509
|
+
// Existing Sentry initialization logic
|
|
2510
|
+
this.sentryIntilization(error, incomingError);
|
|
2511
|
+
}
|
|
2512
|
+
handleNonHttpErrorResponse(error) {
|
|
2513
|
+
if (typeof error === 'object' && 'message' in error) {
|
|
2514
|
+
if (error instanceof HttpErrorResponse) {
|
|
2515
|
+
if (error.status !== StatusCodes.UNAUTHORIZED) {
|
|
2516
|
+
error = new Error(`Object captured as exception: ${error}`); // NOSONAR
|
|
2506
2517
|
}
|
|
2507
|
-
const errorDetails = error
|
|
2508
|
-
? JSON.stringify(error)
|
|
2509
|
-
: 'No more additional error info';
|
|
2510
|
-
const enhancedErrorMessage = `${defaultMessage} | Original error detail: ${errorDetails}`;
|
|
2511
|
-
error = new Error(enhancedErrorMessage);
|
|
2512
2518
|
}
|
|
2513
|
-
//
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
this.logToConsole(error);
|
|
2523
|
-
});
|
|
2519
|
+
// Exclude reporting 401 errors
|
|
2520
|
+
}
|
|
2521
|
+
}
|
|
2522
|
+
errorMessageFormatter(error) {
|
|
2523
|
+
if (!(error instanceof Error) || !error.message) {
|
|
2524
|
+
const defaultMessage = 'Captured an unlabeled event';
|
|
2525
|
+
if (error && 'isTrusted' in error) {
|
|
2526
|
+
console.warn('Ignored isTrusted browser event:', error);
|
|
2527
|
+
return;
|
|
2524
2528
|
}
|
|
2525
|
-
|
|
2529
|
+
const errorDetails = error ? JSON.stringify(error) : 'No more additional error info';
|
|
2530
|
+
const enhancedErrorMessage = `${defaultMessage} | Original error detail: ${errorDetails}`;
|
|
2531
|
+
error = new Error(enhancedErrorMessage); // NOSONAR
|
|
2532
|
+
}
|
|
2533
|
+
}
|
|
2534
|
+
sentryIntilization(error, incomingError) {
|
|
2535
|
+
if (!SentryErrorHandler.sentryInitialized) {
|
|
2536
|
+
this.initializeSentryAsync()
|
|
2537
|
+
.then(() => {
|
|
2526
2538
|
this.logToSentry(error);
|
|
2527
|
-
|
|
2539
|
+
throw incomingError;
|
|
2540
|
+
})
|
|
2541
|
+
.catch(err => {
|
|
2542
|
+
console.error('Error initializing Sentry:', err);
|
|
2543
|
+
this.logToConsole(error);
|
|
2544
|
+
});
|
|
2545
|
+
}
|
|
2546
|
+
else {
|
|
2547
|
+
this.logToSentry(error);
|
|
2528
2548
|
}
|
|
2529
2549
|
}
|
|
2530
2550
|
logToSentry(error) {
|
|
2531
2551
|
try {
|
|
2532
2552
|
const user = SentryErrorHandler.user;
|
|
2533
|
-
|
|
2534
|
-
// Appends user details for sentry log
|
|
2535
|
-
scope.setUser({
|
|
2536
|
-
...user
|
|
2537
|
-
});
|
|
2538
|
-
// Ensure error is properly formatted
|
|
2539
|
-
if (error instanceof Error && error.message) {
|
|
2540
|
-
Sentry.captureException(error);
|
|
2541
|
-
}
|
|
2542
|
-
else if (typeof error === 'object' && error !== null) {
|
|
2543
|
-
// If it's an object but not a standard Error, attempt to log its properties safely
|
|
2544
|
-
let errorMessage = 'Captured non-standard error with no message';
|
|
2545
|
-
// Try to extract any message-like property safely
|
|
2546
|
-
if ('message' in error) {
|
|
2547
|
-
errorMessage = `Error message: ${error.message}`;
|
|
2548
|
-
}
|
|
2549
|
-
else {
|
|
2550
|
-
// Attempt to capture key properties safely
|
|
2551
|
-
try {
|
|
2552
|
-
errorMessage = `Captured non-standard error: ${JSON.stringify(error, Object.getOwnPropertyNames(error))}`;
|
|
2553
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2554
|
-
}
|
|
2555
|
-
catch (jsonError) {
|
|
2556
|
-
errorMessage = `Captured non-standard error with serialization issue: ${jsonError.message}`;
|
|
2557
|
-
}
|
|
2558
|
-
}
|
|
2559
|
-
// Create a new Error object with the enhanced message
|
|
2560
|
-
const errorObject = new Error(errorMessage);
|
|
2561
|
-
Sentry.captureException(errorObject);
|
|
2562
|
-
}
|
|
2563
|
-
else {
|
|
2564
|
-
const defaultMessage = 'Captured an unlabeled event';
|
|
2565
|
-
if (error && 'isTrusted' in error) {
|
|
2566
|
-
console.warn('Ignored isTrusted browser event:', error);
|
|
2567
|
-
return;
|
|
2568
|
-
}
|
|
2569
|
-
const errorDetails = error ? JSON.stringify(error) : 'No additional error info';
|
|
2570
|
-
const enhancedErrorMessage = `${defaultMessage} | Original error details: ${errorDetails}`;
|
|
2571
|
-
const enhancedError = new Error(enhancedErrorMessage);
|
|
2572
|
-
Sentry.captureException(enhancedError);
|
|
2573
|
-
}
|
|
2574
|
-
});
|
|
2553
|
+
this.scopeWithSentry(error, user);
|
|
2575
2554
|
}
|
|
2576
2555
|
catch (e) {
|
|
2577
2556
|
console.error('Unable to log the error to Sentry. An exception occurred:');
|
|
2578
2557
|
console.error(e);
|
|
2579
2558
|
}
|
|
2580
2559
|
}
|
|
2560
|
+
scopeWithSentry(error, user) {
|
|
2561
|
+
Sentry.withScope(scope => {
|
|
2562
|
+
// Appends user details for sentry log
|
|
2563
|
+
scope.setUser({
|
|
2564
|
+
...user
|
|
2565
|
+
});
|
|
2566
|
+
// Ensure error is properly formatted
|
|
2567
|
+
if (error instanceof Error && error.message) {
|
|
2568
|
+
Sentry.captureException(error);
|
|
2569
|
+
}
|
|
2570
|
+
else if (typeof error === 'object' && error !== null) {
|
|
2571
|
+
this.handleNonStandardError(error);
|
|
2572
|
+
}
|
|
2573
|
+
else {
|
|
2574
|
+
this.handleUnlabeledEvent(error);
|
|
2575
|
+
}
|
|
2576
|
+
});
|
|
2577
|
+
}
|
|
2578
|
+
handleNonStandardError(error) {
|
|
2579
|
+
// If it's an object but not a standard Error, attempt to log its properties safely
|
|
2580
|
+
let errorMessage = 'Captured non-standard error with no message'; // NOSONAR
|
|
2581
|
+
// Try to extract any message-like property safely
|
|
2582
|
+
if ('message' in error) {
|
|
2583
|
+
errorMessage = `Error message: ${String(error.message)}`;
|
|
2584
|
+
}
|
|
2585
|
+
else {
|
|
2586
|
+
// Attempt to capture key properties safely
|
|
2587
|
+
try {
|
|
2588
|
+
errorMessage = `Captured non-standard error: ${JSON.stringify(error, Object.getOwnPropertyNames(error))}`;
|
|
2589
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2590
|
+
}
|
|
2591
|
+
catch (jsonError) {
|
|
2592
|
+
errorMessage = `Captured non-standard error with serialization issue: ${jsonError.message}`;
|
|
2593
|
+
}
|
|
2594
|
+
}
|
|
2595
|
+
// Create a new Error object with the enhanced message
|
|
2596
|
+
const errorObject = new Error(errorMessage);
|
|
2597
|
+
Sentry.captureException(errorObject);
|
|
2598
|
+
}
|
|
2599
|
+
handleUnlabeledEvent(error) {
|
|
2600
|
+
const defaultMessage = 'Captured an unlabeled event';
|
|
2601
|
+
if (error && 'isTrusted' in error) {
|
|
2602
|
+
console.warn('Ignored isTrusted browser event:', error);
|
|
2603
|
+
return;
|
|
2604
|
+
}
|
|
2605
|
+
const errorDetails = error ? JSON.stringify(error) : 'No additional error info';
|
|
2606
|
+
const enhancedErrorMessage = `${defaultMessage} | Original error details: ${errorDetails}`;
|
|
2607
|
+
const enhancedError = new Error(enhancedErrorMessage);
|
|
2608
|
+
Sentry.captureException(enhancedError);
|
|
2609
|
+
}
|
|
2581
2610
|
logToConsole(error) {
|
|
2582
2611
|
// Attempt to print in the console
|
|
2583
2612
|
try {
|