@cloudcare/browser-core 1.0.17 → 1.0.20
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/cjs/configuration.js +19 -1
- package/cjs/dataMap.js +1 -0
- package/cjs/errorCollection.js +9 -5
- package/cjs/helper/errorTools.js +39 -1
- package/cjs/helper/tools.js +111 -1
- package/esm/configuration.js +17 -1
- package/esm/dataMap.js +1 -0
- package/esm/errorCollection.js +11 -7
- package/esm/helper/errorTools.js +37 -2
- package/esm/helper/tools.js +108 -1
- package/package.json +2 -2
- package/src/configuration.js +13 -1
- package/src/dataMap.js +1 -0
- package/src/errorCollection.js +12 -7
- package/src/helper/errorTools.js +39 -2
- package/src/helper/tools.js +101 -1
package/cjs/configuration.js
CHANGED
|
@@ -151,5 +151,23 @@ function mustUseSecureCookie(userConfiguration) {
|
|
|
151
151
|
}
|
|
152
152
|
|
|
153
153
|
function isIntakeRequest(url, configuration) {
|
|
154
|
-
return
|
|
154
|
+
// return haveSameOrigin(url, configuration.datakitUrl)
|
|
155
|
+
var notTakeRequest = [configuration.datakitUrl];
|
|
156
|
+
|
|
157
|
+
if (configuration.logsEndpoint) {
|
|
158
|
+
notTakeRequest.push(configuration.logsEndpoint);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
var isIntake = false;
|
|
162
|
+
|
|
163
|
+
for (var _i = 0, _notTakeRequest = notTakeRequest; _i < _notTakeRequest.length; _i++) {
|
|
164
|
+
var _url = _notTakeRequest[_i];
|
|
165
|
+
|
|
166
|
+
if (url.indexOf(_url) === 0) {
|
|
167
|
+
isIntake = true;
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return isIntake;
|
|
155
173
|
}
|
package/cjs/dataMap.js
CHANGED
|
@@ -102,6 +102,7 @@ var dataMap = {
|
|
|
102
102
|
tags: {
|
|
103
103
|
error_source: 'error.source',
|
|
104
104
|
error_type: 'error.type',
|
|
105
|
+
error_handling: 'error.handling',
|
|
105
106
|
resource_url: 'error.resource.url',
|
|
106
107
|
resource_url_host: 'error.resource.url_host',
|
|
107
108
|
resource_url_path: 'error.resource.url_path',
|
package/cjs/errorCollection.js
CHANGED
|
@@ -46,14 +46,16 @@ function startConsoleTracking(errorObservable) {
|
|
|
46
46
|
|
|
47
47
|
console.error = function () {
|
|
48
48
|
originalConsoleError.apply(console, arguments);
|
|
49
|
-
|
|
49
|
+
var handlingStack = (0, _errorTools.createHandlingStack)();
|
|
50
|
+
errorObservable.notify((0, _tools.extend)({}, buildErrorFromParams((0, _tools.toArray)(arguments), handlingStack), {
|
|
50
51
|
source: _errorTools.ErrorSource.CONSOLE,
|
|
51
|
-
startClocks: (0, _tools.clocksNow)()
|
|
52
|
+
startClocks: (0, _tools.clocksNow)(),
|
|
53
|
+
handling: _enums.ErrorHandling.HANDLED
|
|
52
54
|
}));
|
|
53
55
|
};
|
|
54
56
|
}
|
|
55
57
|
|
|
56
|
-
function buildErrorFromParams(params) {
|
|
58
|
+
function buildErrorFromParams(params, handlingStack) {
|
|
57
59
|
var firstErrorParam = (0, _tools.find)(params, function (param) {
|
|
58
60
|
return param instanceof Error;
|
|
59
61
|
});
|
|
@@ -63,7 +65,8 @@ function buildErrorFromParams(params) {
|
|
|
63
65
|
}).join(' ');
|
|
64
66
|
return {
|
|
65
67
|
message: message,
|
|
66
|
-
stack: firstErrorParam ? (0, _errorTools.toStackTraceString)((0, _tracekit.computeStackTrace)(firstErrorParam)) : undefined
|
|
68
|
+
stack: firstErrorParam ? (0, _errorTools.toStackTraceString)((0, _tracekit.computeStackTrace)(firstErrorParam)) : undefined,
|
|
69
|
+
handlingStack: handlingStack
|
|
67
70
|
};
|
|
68
71
|
}
|
|
69
72
|
|
|
@@ -93,7 +96,8 @@ function startRuntimeErrorTracking(errorObservable) {
|
|
|
93
96
|
stack: error.stack,
|
|
94
97
|
type: error.type,
|
|
95
98
|
source: _errorTools.ErrorSource.SOURCE,
|
|
96
|
-
startClocks: (0, _tools.clocksNow)()
|
|
99
|
+
startClocks: (0, _tools.clocksNow)(),
|
|
100
|
+
handling: _enums.ErrorHandling.UNHANDLED
|
|
97
101
|
});
|
|
98
102
|
};
|
|
99
103
|
|
package/cjs/helper/errorTools.js
CHANGED
|
@@ -4,12 +4,15 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.formatUnknownError = formatUnknownError;
|
|
7
|
+
exports.createHandlingStack = createHandlingStack;
|
|
7
8
|
exports.toStackTraceString = toStackTraceString;
|
|
8
9
|
exports.formatErrorMessage = formatErrorMessage;
|
|
9
10
|
exports.ErrorSource = void 0;
|
|
10
11
|
|
|
11
12
|
var _tools = require("./tools");
|
|
12
13
|
|
|
14
|
+
var _tracekit = require("../tracekit");
|
|
15
|
+
|
|
13
16
|
var ErrorSource = {
|
|
14
17
|
AGENT: 'agent',
|
|
15
18
|
CONSOLE: 'console',
|
|
@@ -20,11 +23,12 @@ var ErrorSource = {
|
|
|
20
23
|
};
|
|
21
24
|
exports.ErrorSource = ErrorSource;
|
|
22
25
|
|
|
23
|
-
function formatUnknownError(stackTrace, errorObject, nonErrorPrefix) {
|
|
26
|
+
function formatUnknownError(stackTrace, errorObject, nonErrorPrefix, handlingStack) {
|
|
24
27
|
if (!stackTrace || stackTrace.message === undefined && !(errorObject instanceof Error)) {
|
|
25
28
|
return {
|
|
26
29
|
message: nonErrorPrefix + '' + JSON.stringify(errorObject),
|
|
27
30
|
stack: 'No stack, consider using an instance of Error',
|
|
31
|
+
handlingStack: handlingStack,
|
|
28
32
|
type: stackTrace && stackTrace.name
|
|
29
33
|
};
|
|
30
34
|
}
|
|
@@ -32,9 +36,43 @@ function formatUnknownError(stackTrace, errorObject, nonErrorPrefix) {
|
|
|
32
36
|
return {
|
|
33
37
|
message: stackTrace.message || 'Empty message',
|
|
34
38
|
stack: toStackTraceString(stackTrace),
|
|
39
|
+
handlingStack: handlingStack,
|
|
35
40
|
type: stackTrace.name
|
|
36
41
|
};
|
|
37
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
Creates a stacktrace without SDK internal frames.
|
|
45
|
+
|
|
46
|
+
Constraints:
|
|
47
|
+
- Has to be called at the utmost position of the call stack.
|
|
48
|
+
- No internal monitoring should encapsulate the function, that is why we need to use callMonitored inside of it.
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
function createHandlingStack() {
|
|
53
|
+
/**
|
|
54
|
+
* Skip the two internal frames:
|
|
55
|
+
* - SDK API (console.error, ...)
|
|
56
|
+
* - this function
|
|
57
|
+
* in order to keep only the user calls
|
|
58
|
+
*/
|
|
59
|
+
var internalFramesToSkip = 2;
|
|
60
|
+
var error = new Error();
|
|
61
|
+
var formattedStack; // IE needs to throw the error to fill in the stack trace
|
|
62
|
+
|
|
63
|
+
if (!error.stack) {
|
|
64
|
+
try {
|
|
65
|
+
throw error;
|
|
66
|
+
} catch (e) {
|
|
67
|
+
(0, _tools.noop)();
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
var stackTrace = (0, _tracekit.computeStackTrace)(error);
|
|
72
|
+
stackTrace.stack = stackTrace.stack.slice(internalFramesToSkip);
|
|
73
|
+
formattedStack = toStackTraceString(stackTrace);
|
|
74
|
+
return formattedStack;
|
|
75
|
+
}
|
|
38
76
|
|
|
39
77
|
function toStackTraceString(stack) {
|
|
40
78
|
var result = stack.name || 'Error' + ': ' + stack.message;
|
package/cjs/helper/tools.js
CHANGED
|
@@ -5,6 +5,9 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.UUID = UUID;
|
|
7
7
|
exports.replaceNumberCharByPath = replaceNumberCharByPath;
|
|
8
|
+
exports.getType = getType;
|
|
9
|
+
exports.mergeInto = mergeInto;
|
|
10
|
+
exports.deepClone = deepClone;
|
|
8
11
|
exports.getStatusGroup = getStatusGroup;
|
|
9
12
|
exports.jsonStringify = jsonStringify;
|
|
10
13
|
exports.noop = noop;
|
|
@@ -717,7 +720,7 @@ function UUID(placeholder) {
|
|
|
717
720
|
|
|
718
721
|
function replaceNumberCharByPath(path) {
|
|
719
722
|
if (path) {
|
|
720
|
-
return path.replace(/\/([^\/]*)\d([^\/]*)/g, '/?');
|
|
723
|
+
return path.replace(/\/([^\/]*)\d([^\/]*)/g, '/?').replace(/\/$/g, '');
|
|
721
724
|
} else {
|
|
722
725
|
return '';
|
|
723
726
|
}
|
|
@@ -1312,6 +1315,113 @@ var getURLSearchParams = function getURLSearchParams(queryString) {
|
|
|
1312
1315
|
|
|
1313
1316
|
exports.getURLSearchParams = getURLSearchParams;
|
|
1314
1317
|
|
|
1318
|
+
function createCircularReferenceChecker() {
|
|
1319
|
+
if (typeof WeakSet !== 'undefined') {
|
|
1320
|
+
var set = new WeakSet();
|
|
1321
|
+
return {
|
|
1322
|
+
hasAlreadyBeenSeen: function hasAlreadyBeenSeen(value) {
|
|
1323
|
+
var has = set.has(value);
|
|
1324
|
+
|
|
1325
|
+
if (!has) {
|
|
1326
|
+
set.add(value);
|
|
1327
|
+
}
|
|
1328
|
+
|
|
1329
|
+
return has;
|
|
1330
|
+
}
|
|
1331
|
+
};
|
|
1332
|
+
}
|
|
1333
|
+
|
|
1334
|
+
var array = [];
|
|
1335
|
+
return {
|
|
1336
|
+
hasAlreadyBeenSeen: function hasAlreadyBeenSeen(value) {
|
|
1337
|
+
var has = array.indexOf(value) >= 0;
|
|
1338
|
+
|
|
1339
|
+
if (!has) {
|
|
1340
|
+
array.push(value);
|
|
1341
|
+
}
|
|
1342
|
+
|
|
1343
|
+
return has;
|
|
1344
|
+
}
|
|
1345
|
+
};
|
|
1346
|
+
}
|
|
1347
|
+
/**
|
|
1348
|
+
* Similar to `typeof`, but distinguish plain objects from `null` and arrays
|
|
1349
|
+
*/
|
|
1350
|
+
|
|
1351
|
+
|
|
1352
|
+
function getType(value) {
|
|
1353
|
+
if (value === null) {
|
|
1354
|
+
return 'null';
|
|
1355
|
+
}
|
|
1356
|
+
|
|
1357
|
+
if (Array.isArray(value)) {
|
|
1358
|
+
return 'array';
|
|
1359
|
+
}
|
|
1360
|
+
|
|
1361
|
+
return _typeof(value);
|
|
1362
|
+
}
|
|
1363
|
+
/**
|
|
1364
|
+
* Iterate over source and affect its sub values into destination, recursively.
|
|
1365
|
+
* If the source and destination can't be merged, return source.
|
|
1366
|
+
*/
|
|
1367
|
+
|
|
1368
|
+
|
|
1369
|
+
function mergeInto(destination, source, circularReferenceChecker) {
|
|
1370
|
+
// ignore the source if it is undefined
|
|
1371
|
+
if (typeof circularReferenceChecker === 'undefined') {
|
|
1372
|
+
circularReferenceChecker = createCircularReferenceChecker();
|
|
1373
|
+
}
|
|
1374
|
+
|
|
1375
|
+
if (source === undefined) {
|
|
1376
|
+
return destination;
|
|
1377
|
+
}
|
|
1378
|
+
|
|
1379
|
+
if (_typeof(source) !== 'object' || source === null) {
|
|
1380
|
+
// primitive values - just return source
|
|
1381
|
+
return source;
|
|
1382
|
+
} else if (source instanceof Date) {
|
|
1383
|
+
return new Date(source.getTime());
|
|
1384
|
+
} else if (source instanceof RegExp) {
|
|
1385
|
+
var flags = source.flags || // old browsers compatibility
|
|
1386
|
+
[source.global ? 'g' : '', source.ignoreCase ? 'i' : '', source.multiline ? 'm' : '', source.sticky ? 'y' : '', source.unicode ? 'u' : ''].join('');
|
|
1387
|
+
return new RegExp(source.source, flags);
|
|
1388
|
+
}
|
|
1389
|
+
|
|
1390
|
+
if (circularReferenceChecker.hasAlreadyBeenSeen(source)) {
|
|
1391
|
+
// remove circular references
|
|
1392
|
+
return undefined;
|
|
1393
|
+
} else if (Array.isArray(source)) {
|
|
1394
|
+
var merged = Array.isArray(destination) ? destination : [];
|
|
1395
|
+
|
|
1396
|
+
for (var i = 0; i < source.length; ++i) {
|
|
1397
|
+
merged[i] = mergeInto(merged[i], source[i], circularReferenceChecker);
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1400
|
+
return merged;
|
|
1401
|
+
}
|
|
1402
|
+
|
|
1403
|
+
var merged = getType(destination) === 'object' ? destination : {};
|
|
1404
|
+
|
|
1405
|
+
for (var key in source) {
|
|
1406
|
+
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
1407
|
+
merged[key] = mergeInto(merged[key], source[key], circularReferenceChecker);
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1410
|
+
|
|
1411
|
+
return merged;
|
|
1412
|
+
}
|
|
1413
|
+
/**
|
|
1414
|
+
* A simplistic implementation of a deep clone algorithm.
|
|
1415
|
+
* Caveats:
|
|
1416
|
+
* - It doesn't maintain prototype chains - don't use with instances of custom classes.
|
|
1417
|
+
* - It doesn't handle Map and Set
|
|
1418
|
+
*/
|
|
1419
|
+
|
|
1420
|
+
|
|
1421
|
+
function deepClone(value) {
|
|
1422
|
+
return mergeInto(undefined, value);
|
|
1423
|
+
}
|
|
1424
|
+
|
|
1315
1425
|
var _URL = function _URL(url) {
|
|
1316
1426
|
var result = {};
|
|
1317
1427
|
var basicProps = ['hash', 'host', 'hostname', 'href', 'origin', 'password', 'pathname', 'port', 'protocol', 'search', 'username'];
|
package/esm/configuration.js
CHANGED
|
@@ -136,5 +136,21 @@ function mustUseSecureCookie(userConfiguration) {
|
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
export function isIntakeRequest(url, configuration) {
|
|
139
|
-
return haveSameOrigin(url, configuration.datakitUrl)
|
|
139
|
+
// return haveSameOrigin(url, configuration.datakitUrl)
|
|
140
|
+
var notTakeRequest = [configuration.datakitUrl];
|
|
141
|
+
|
|
142
|
+
if (configuration.logsEndpoint) {
|
|
143
|
+
notTakeRequest.push(configuration.logsEndpoint);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
var isIntake = false;
|
|
147
|
+
|
|
148
|
+
for (var _url of notTakeRequest) {
|
|
149
|
+
if (url.indexOf(_url) === 0) {
|
|
150
|
+
isIntake = true;
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return isIntake;
|
|
140
156
|
}
|
package/esm/dataMap.js
CHANGED
|
@@ -93,6 +93,7 @@ export var dataMap = {
|
|
|
93
93
|
tags: {
|
|
94
94
|
error_source: 'error.source',
|
|
95
95
|
error_type: 'error.type',
|
|
96
|
+
error_handling: 'error.handling',
|
|
96
97
|
resource_url: 'error.resource.url',
|
|
97
98
|
resource_url_host: 'error.resource.url_host',
|
|
98
99
|
resource_url_path: 'error.resource.url_path',
|
package/esm/errorCollection.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { toArray, jsonStringify, find, clocksNow, map, extend } from './helper/tools';
|
|
2
|
-
import { ErrorSource, formatUnknownError, toStackTraceString, formatErrorMessage } from './helper/errorTools';
|
|
2
|
+
import { ErrorSource, formatUnknownError, toStackTraceString, formatErrorMessage, createHandlingStack } from './helper/errorTools';
|
|
3
3
|
import { computeStackTrace, subscribe, unsubscribe } from './tracekit';
|
|
4
4
|
import { Observable } from './helper/observable';
|
|
5
5
|
import { isIntakeRequest } from './configuration';
|
|
6
|
-
import { RequestType } from './helper/enums';
|
|
6
|
+
import { RequestType, ErrorHandling } from './helper/enums';
|
|
7
7
|
import { resetXhrProxy, startXhrProxy } from './xhrProxy';
|
|
8
8
|
import { resetFetchProxy, startFetchProxy } from './fetchProxy';
|
|
9
9
|
var errorObservable;
|
|
@@ -23,14 +23,16 @@ export function startConsoleTracking(errorObservable) {
|
|
|
23
23
|
|
|
24
24
|
console.error = function () {
|
|
25
25
|
originalConsoleError.apply(console, arguments);
|
|
26
|
-
|
|
26
|
+
var handlingStack = createHandlingStack();
|
|
27
|
+
errorObservable.notify(extend({}, buildErrorFromParams(toArray(arguments), handlingStack), {
|
|
27
28
|
source: ErrorSource.CONSOLE,
|
|
28
|
-
startClocks: clocksNow()
|
|
29
|
+
startClocks: clocksNow(),
|
|
30
|
+
handling: ErrorHandling.HANDLED
|
|
29
31
|
}));
|
|
30
32
|
};
|
|
31
33
|
}
|
|
32
34
|
|
|
33
|
-
function buildErrorFromParams(params) {
|
|
35
|
+
function buildErrorFromParams(params, handlingStack) {
|
|
34
36
|
var firstErrorParam = find(params, function (param) {
|
|
35
37
|
return param instanceof Error;
|
|
36
38
|
});
|
|
@@ -40,7 +42,8 @@ function buildErrorFromParams(params) {
|
|
|
40
42
|
}).join(' ');
|
|
41
43
|
return {
|
|
42
44
|
message: message,
|
|
43
|
-
stack: firstErrorParam ? toStackTraceString(computeStackTrace(firstErrorParam)) : undefined
|
|
45
|
+
stack: firstErrorParam ? toStackTraceString(computeStackTrace(firstErrorParam)) : undefined,
|
|
46
|
+
handlingStack: handlingStack
|
|
44
47
|
};
|
|
45
48
|
}
|
|
46
49
|
|
|
@@ -69,7 +72,8 @@ export function startRuntimeErrorTracking(errorObservable) {
|
|
|
69
72
|
stack: error.stack,
|
|
70
73
|
type: error.type,
|
|
71
74
|
source: ErrorSource.SOURCE,
|
|
72
|
-
startClocks: clocksNow()
|
|
75
|
+
startClocks: clocksNow(),
|
|
76
|
+
handling: ErrorHandling.UNHANDLED
|
|
73
77
|
});
|
|
74
78
|
};
|
|
75
79
|
|
package/esm/helper/errorTools.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { each } from './tools';
|
|
1
|
+
import { each, noop } from './tools';
|
|
2
|
+
import { computeStackTrace } from '../tracekit';
|
|
2
3
|
export var ErrorSource = {
|
|
3
4
|
AGENT: 'agent',
|
|
4
5
|
CONSOLE: 'console',
|
|
@@ -7,11 +8,12 @@ export var ErrorSource = {
|
|
|
7
8
|
LOGGER: 'logger',
|
|
8
9
|
CUSTOM: 'custom'
|
|
9
10
|
};
|
|
10
|
-
export function formatUnknownError(stackTrace, errorObject, nonErrorPrefix) {
|
|
11
|
+
export function formatUnknownError(stackTrace, errorObject, nonErrorPrefix, handlingStack) {
|
|
11
12
|
if (!stackTrace || stackTrace.message === undefined && !(errorObject instanceof Error)) {
|
|
12
13
|
return {
|
|
13
14
|
message: nonErrorPrefix + '' + JSON.stringify(errorObject),
|
|
14
15
|
stack: 'No stack, consider using an instance of Error',
|
|
16
|
+
handlingStack: handlingStack,
|
|
15
17
|
type: stackTrace && stackTrace.name
|
|
16
18
|
};
|
|
17
19
|
}
|
|
@@ -19,9 +21,42 @@ export function formatUnknownError(stackTrace, errorObject, nonErrorPrefix) {
|
|
|
19
21
|
return {
|
|
20
22
|
message: stackTrace.message || 'Empty message',
|
|
21
23
|
stack: toStackTraceString(stackTrace),
|
|
24
|
+
handlingStack: handlingStack,
|
|
22
25
|
type: stackTrace.name
|
|
23
26
|
};
|
|
24
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
Creates a stacktrace without SDK internal frames.
|
|
30
|
+
|
|
31
|
+
Constraints:
|
|
32
|
+
- Has to be called at the utmost position of the call stack.
|
|
33
|
+
- No internal monitoring should encapsulate the function, that is why we need to use callMonitored inside of it.
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
export function createHandlingStack() {
|
|
37
|
+
/**
|
|
38
|
+
* Skip the two internal frames:
|
|
39
|
+
* - SDK API (console.error, ...)
|
|
40
|
+
* - this function
|
|
41
|
+
* in order to keep only the user calls
|
|
42
|
+
*/
|
|
43
|
+
var internalFramesToSkip = 2;
|
|
44
|
+
var error = new Error();
|
|
45
|
+
var formattedStack; // IE needs to throw the error to fill in the stack trace
|
|
46
|
+
|
|
47
|
+
if (!error.stack) {
|
|
48
|
+
try {
|
|
49
|
+
throw error;
|
|
50
|
+
} catch (e) {
|
|
51
|
+
noop();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
var stackTrace = computeStackTrace(error);
|
|
56
|
+
stackTrace.stack = stackTrace.stack.slice(internalFramesToSkip);
|
|
57
|
+
formattedStack = toStackTraceString(stackTrace);
|
|
58
|
+
return formattedStack;
|
|
59
|
+
}
|
|
25
60
|
export function toStackTraceString(stack) {
|
|
26
61
|
var result = stack.name || 'Error' + ': ' + stack.message;
|
|
27
62
|
each(stack.stack, function (frame) {
|
package/esm/helper/tools.js
CHANGED
|
@@ -543,7 +543,7 @@ export function UUID(placeholder) {
|
|
|
543
543
|
|
|
544
544
|
export function replaceNumberCharByPath(path) {
|
|
545
545
|
if (path) {
|
|
546
|
-
return path.replace(/\/([^\/]*)\d([^\/]*)/g, '/?');
|
|
546
|
+
return path.replace(/\/([^\/]*)\d([^\/]*)/g, '/?').replace(/\/$/g, '');
|
|
547
547
|
} else {
|
|
548
548
|
return '';
|
|
549
549
|
}
|
|
@@ -1098,6 +1098,113 @@ export var getURLSearchParams = function getURLSearchParams(queryString) {
|
|
|
1098
1098
|
|
|
1099
1099
|
return args;
|
|
1100
1100
|
};
|
|
1101
|
+
|
|
1102
|
+
function createCircularReferenceChecker() {
|
|
1103
|
+
if (typeof WeakSet !== 'undefined') {
|
|
1104
|
+
var set = new WeakSet();
|
|
1105
|
+
return {
|
|
1106
|
+
hasAlreadyBeenSeen(value) {
|
|
1107
|
+
var has = set.has(value);
|
|
1108
|
+
|
|
1109
|
+
if (!has) {
|
|
1110
|
+
set.add(value);
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
return has;
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
};
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1119
|
+
var array = [];
|
|
1120
|
+
return {
|
|
1121
|
+
hasAlreadyBeenSeen(value) {
|
|
1122
|
+
var has = array.indexOf(value) >= 0;
|
|
1123
|
+
|
|
1124
|
+
if (!has) {
|
|
1125
|
+
array.push(value);
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
return has;
|
|
1129
|
+
}
|
|
1130
|
+
|
|
1131
|
+
};
|
|
1132
|
+
}
|
|
1133
|
+
/**
|
|
1134
|
+
* Similar to `typeof`, but distinguish plain objects from `null` and arrays
|
|
1135
|
+
*/
|
|
1136
|
+
|
|
1137
|
+
|
|
1138
|
+
export function getType(value) {
|
|
1139
|
+
if (value === null) {
|
|
1140
|
+
return 'null';
|
|
1141
|
+
}
|
|
1142
|
+
|
|
1143
|
+
if (Array.isArray(value)) {
|
|
1144
|
+
return 'array';
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1147
|
+
return typeof value;
|
|
1148
|
+
}
|
|
1149
|
+
/**
|
|
1150
|
+
* Iterate over source and affect its sub values into destination, recursively.
|
|
1151
|
+
* If the source and destination can't be merged, return source.
|
|
1152
|
+
*/
|
|
1153
|
+
|
|
1154
|
+
export function mergeInto(destination, source, circularReferenceChecker) {
|
|
1155
|
+
// ignore the source if it is undefined
|
|
1156
|
+
if (typeof circularReferenceChecker === 'undefined') {
|
|
1157
|
+
circularReferenceChecker = createCircularReferenceChecker();
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
if (source === undefined) {
|
|
1161
|
+
return destination;
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1164
|
+
if (typeof source !== 'object' || source === null) {
|
|
1165
|
+
// primitive values - just return source
|
|
1166
|
+
return source;
|
|
1167
|
+
} else if (source instanceof Date) {
|
|
1168
|
+
return new Date(source.getTime());
|
|
1169
|
+
} else if (source instanceof RegExp) {
|
|
1170
|
+
var flags = source.flags || // old browsers compatibility
|
|
1171
|
+
[source.global ? 'g' : '', source.ignoreCase ? 'i' : '', source.multiline ? 'm' : '', source.sticky ? 'y' : '', source.unicode ? 'u' : ''].join('');
|
|
1172
|
+
return new RegExp(source.source, flags);
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1175
|
+
if (circularReferenceChecker.hasAlreadyBeenSeen(source)) {
|
|
1176
|
+
// remove circular references
|
|
1177
|
+
return undefined;
|
|
1178
|
+
} else if (Array.isArray(source)) {
|
|
1179
|
+
var merged = Array.isArray(destination) ? destination : [];
|
|
1180
|
+
|
|
1181
|
+
for (var i = 0; i < source.length; ++i) {
|
|
1182
|
+
merged[i] = mergeInto(merged[i], source[i], circularReferenceChecker);
|
|
1183
|
+
}
|
|
1184
|
+
|
|
1185
|
+
return merged;
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
var merged = getType(destination) === 'object' ? destination : {};
|
|
1189
|
+
|
|
1190
|
+
for (var key in source) {
|
|
1191
|
+
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
1192
|
+
merged[key] = mergeInto(merged[key], source[key], circularReferenceChecker);
|
|
1193
|
+
}
|
|
1194
|
+
}
|
|
1195
|
+
|
|
1196
|
+
return merged;
|
|
1197
|
+
}
|
|
1198
|
+
/**
|
|
1199
|
+
* A simplistic implementation of a deep clone algorithm.
|
|
1200
|
+
* Caveats:
|
|
1201
|
+
* - It doesn't maintain prototype chains - don't use with instances of custom classes.
|
|
1202
|
+
* - It doesn't handle Map and Set
|
|
1203
|
+
*/
|
|
1204
|
+
|
|
1205
|
+
export function deepClone(value) {
|
|
1206
|
+
return mergeInto(undefined, value);
|
|
1207
|
+
}
|
|
1101
1208
|
export var _URL = function _URL(url) {
|
|
1102
1209
|
var result = {};
|
|
1103
1210
|
var basicProps = ['hash', 'host', 'hostname', 'href', 'origin', 'password', 'pathname', 'port', 'protocol', 'search', 'username'];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudcare/browser-core",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.20",
|
|
4
4
|
"main": "cjs/index.js",
|
|
5
5
|
"module": "esm/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -20,5 +20,5 @@
|
|
|
20
20
|
"author": "dataflux",
|
|
21
21
|
"license": "MIT",
|
|
22
22
|
"description": "DataFlux RUM Web 端数据指标监控",
|
|
23
|
-
"gitHead": "
|
|
23
|
+
"gitHead": "a80f418bef92d7c86b3965fee63e6dc11f11b9e9"
|
|
24
24
|
}
|
package/src/configuration.js
CHANGED
|
@@ -132,5 +132,17 @@ function mustUseSecureCookie(userConfiguration) {
|
|
|
132
132
|
}
|
|
133
133
|
|
|
134
134
|
export function isIntakeRequest(url, configuration) {
|
|
135
|
-
return haveSameOrigin(url, configuration.datakitUrl)
|
|
135
|
+
// return haveSameOrigin(url, configuration.datakitUrl)
|
|
136
|
+
var notTakeRequest = [configuration.datakitUrl]
|
|
137
|
+
if (configuration.logsEndpoint) {
|
|
138
|
+
notTakeRequest.push(configuration.logsEndpoint)
|
|
139
|
+
}
|
|
140
|
+
var isIntake = false
|
|
141
|
+
for(var _url of notTakeRequest) {
|
|
142
|
+
if (url.indexOf(_url) === 0) {
|
|
143
|
+
isIntake = true
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return isIntake
|
|
136
148
|
}
|
package/src/dataMap.js
CHANGED
|
@@ -93,6 +93,7 @@ export var dataMap = {
|
|
|
93
93
|
tags: {
|
|
94
94
|
error_source: 'error.source',
|
|
95
95
|
error_type: 'error.type',
|
|
96
|
+
error_handling: 'error.handling',
|
|
96
97
|
resource_url: 'error.resource.url',
|
|
97
98
|
resource_url_host: 'error.resource.url_host',
|
|
98
99
|
resource_url_path: 'error.resource.url_path',
|
package/src/errorCollection.js
CHANGED
|
@@ -10,12 +10,13 @@ import {
|
|
|
10
10
|
ErrorSource,
|
|
11
11
|
formatUnknownError,
|
|
12
12
|
toStackTraceString,
|
|
13
|
-
formatErrorMessage
|
|
13
|
+
formatErrorMessage,
|
|
14
|
+
createHandlingStack
|
|
14
15
|
} from './helper/errorTools'
|
|
15
16
|
import { computeStackTrace, subscribe, unsubscribe } from './tracekit'
|
|
16
17
|
import { Observable } from './helper/observable'
|
|
17
18
|
import { isIntakeRequest } from './configuration'
|
|
18
|
-
import { RequestType } from './helper/enums'
|
|
19
|
+
import { RequestType, ErrorHandling } from './helper/enums'
|
|
19
20
|
import { resetXhrProxy, startXhrProxy } from './xhrProxy'
|
|
20
21
|
import { resetFetchProxy, startFetchProxy } from './fetchProxy'
|
|
21
22
|
|
|
@@ -37,16 +38,18 @@ export function startConsoleTracking(errorObservable) {
|
|
|
37
38
|
originalConsoleError = console.error
|
|
38
39
|
console.error = function () {
|
|
39
40
|
originalConsoleError.apply(console, arguments)
|
|
41
|
+
const handlingStack = createHandlingStack()
|
|
40
42
|
errorObservable.notify(
|
|
41
|
-
extend({}, buildErrorFromParams(toArray(arguments)), {
|
|
43
|
+
extend({}, buildErrorFromParams(toArray(arguments), handlingStack), {
|
|
42
44
|
source: ErrorSource.CONSOLE,
|
|
43
|
-
startClocks: clocksNow()
|
|
45
|
+
startClocks: clocksNow(),
|
|
46
|
+
handling: ErrorHandling.HANDLED
|
|
44
47
|
})
|
|
45
48
|
)
|
|
46
49
|
}
|
|
47
50
|
}
|
|
48
51
|
|
|
49
|
-
function buildErrorFromParams(params) {
|
|
52
|
+
function buildErrorFromParams(params, handlingStack) {
|
|
50
53
|
var firstErrorParam = find(params, function (param) {
|
|
51
54
|
return param instanceof Error
|
|
52
55
|
})
|
|
@@ -58,7 +61,8 @@ function buildErrorFromParams(params) {
|
|
|
58
61
|
message: message,
|
|
59
62
|
stack: firstErrorParam
|
|
60
63
|
? toStackTraceString(computeStackTrace(firstErrorParam))
|
|
61
|
-
: undefined
|
|
64
|
+
: undefined,
|
|
65
|
+
handlingStack: handlingStack
|
|
62
66
|
}
|
|
63
67
|
}
|
|
64
68
|
|
|
@@ -86,7 +90,8 @@ export function startRuntimeErrorTracking(errorObservable) {
|
|
|
86
90
|
stack: error.stack,
|
|
87
91
|
type: error.type,
|
|
88
92
|
source: ErrorSource.SOURCE,
|
|
89
|
-
startClocks: clocksNow()
|
|
93
|
+
startClocks: clocksNow(),
|
|
94
|
+
handling: ErrorHandling.UNHANDLED
|
|
90
95
|
})
|
|
91
96
|
}
|
|
92
97
|
|
package/src/helper/errorTools.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { each } from './tools'
|
|
1
|
+
import { each , noop} from './tools'
|
|
2
|
+
import { computeStackTrace} from '../tracekit'
|
|
3
|
+
|
|
2
4
|
export var ErrorSource = {
|
|
3
5
|
AGENT: 'agent',
|
|
4
6
|
CONSOLE: 'console',
|
|
@@ -7,7 +9,8 @@ export var ErrorSource = {
|
|
|
7
9
|
LOGGER: 'logger',
|
|
8
10
|
CUSTOM: 'custom'
|
|
9
11
|
}
|
|
10
|
-
|
|
12
|
+
|
|
13
|
+
export function formatUnknownError(stackTrace, errorObject, nonErrorPrefix,handlingStack) {
|
|
11
14
|
if (
|
|
12
15
|
!stackTrace ||
|
|
13
16
|
(stackTrace.message === undefined && !(errorObject instanceof Error))
|
|
@@ -15,16 +18,50 @@ export function formatUnknownError(stackTrace, errorObject, nonErrorPrefix) {
|
|
|
15
18
|
return {
|
|
16
19
|
message: nonErrorPrefix + '' + JSON.stringify(errorObject),
|
|
17
20
|
stack: 'No stack, consider using an instance of Error',
|
|
21
|
+
handlingStack:handlingStack,
|
|
18
22
|
type: stackTrace && stackTrace.name
|
|
19
23
|
}
|
|
20
24
|
}
|
|
21
25
|
return {
|
|
22
26
|
message: stackTrace.message || 'Empty message',
|
|
23
27
|
stack: toStackTraceString(stackTrace),
|
|
28
|
+
handlingStack:handlingStack,
|
|
24
29
|
type: stackTrace.name
|
|
25
30
|
}
|
|
26
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
Creates a stacktrace without SDK internal frames.
|
|
34
|
+
|
|
35
|
+
Constraints:
|
|
36
|
+
- Has to be called at the utmost position of the call stack.
|
|
37
|
+
- No internal monitoring should encapsulate the function, that is why we need to use callMonitored inside of it.
|
|
38
|
+
*/
|
|
39
|
+
export function createHandlingStack() {
|
|
40
|
+
/**
|
|
41
|
+
* Skip the two internal frames:
|
|
42
|
+
* - SDK API (console.error, ...)
|
|
43
|
+
* - this function
|
|
44
|
+
* in order to keep only the user calls
|
|
45
|
+
*/
|
|
46
|
+
const internalFramesToSkip = 2
|
|
47
|
+
const error = new Error()
|
|
48
|
+
let formattedStack
|
|
27
49
|
|
|
50
|
+
// IE needs to throw the error to fill in the stack trace
|
|
51
|
+
if (!error.stack) {
|
|
52
|
+
try {
|
|
53
|
+
throw error
|
|
54
|
+
} catch (e) {
|
|
55
|
+
noop()
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const stackTrace = computeStackTrace(error)
|
|
60
|
+
stackTrace.stack = stackTrace.stack.slice(internalFramesToSkip)
|
|
61
|
+
formattedStack = toStackTraceString(stackTrace)
|
|
62
|
+
|
|
63
|
+
return formattedStack
|
|
64
|
+
}
|
|
28
65
|
export function toStackTraceString(stack) {
|
|
29
66
|
var result = stack.name || 'Error' + ': ' + stack.message
|
|
30
67
|
each(stack.stack, function (frame) {
|
package/src/helper/tools.js
CHANGED
|
@@ -536,7 +536,7 @@ export function UUID(placeholder) {
|
|
|
536
536
|
// 替换url包含数字的路由
|
|
537
537
|
export function replaceNumberCharByPath(path) {
|
|
538
538
|
if (path) {
|
|
539
|
-
return path.replace(/\/([^\/]*)\d([^\/]*)/g, '/?')
|
|
539
|
+
return path.replace(/\/([^\/]*)\d([^\/]*)/g, '/?').replace(/\/$/g, '')
|
|
540
540
|
} else {
|
|
541
541
|
return ''
|
|
542
542
|
}
|
|
@@ -1064,7 +1064,107 @@ export var getURLSearchParams = function (queryString) {
|
|
|
1064
1064
|
}
|
|
1065
1065
|
return args
|
|
1066
1066
|
}
|
|
1067
|
+
function createCircularReferenceChecker() {
|
|
1068
|
+
if (typeof WeakSet !== 'undefined') {
|
|
1069
|
+
var set = new WeakSet()
|
|
1070
|
+
return {
|
|
1071
|
+
hasAlreadyBeenSeen(value) {
|
|
1072
|
+
var has = set.has(value)
|
|
1073
|
+
if (!has) {
|
|
1074
|
+
set.add(value)
|
|
1075
|
+
}
|
|
1076
|
+
return has
|
|
1077
|
+
},
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
var array = []
|
|
1081
|
+
return {
|
|
1082
|
+
hasAlreadyBeenSeen(value) {
|
|
1083
|
+
var has = array.indexOf(value) >= 0
|
|
1084
|
+
if (!has) {
|
|
1085
|
+
array.push(value)
|
|
1086
|
+
}
|
|
1087
|
+
return has
|
|
1088
|
+
},
|
|
1089
|
+
}
|
|
1090
|
+
}
|
|
1091
|
+
/**
|
|
1092
|
+
* Similar to `typeof`, but distinguish plain objects from `null` and arrays
|
|
1093
|
+
*/
|
|
1094
|
+
export function getType(value) {
|
|
1095
|
+
if (value === null) {
|
|
1096
|
+
return 'null'
|
|
1097
|
+
}
|
|
1098
|
+
if (Array.isArray(value)) {
|
|
1099
|
+
return 'array'
|
|
1100
|
+
}
|
|
1101
|
+
return typeof value
|
|
1102
|
+
}
|
|
1103
|
+
/**
|
|
1104
|
+
* Iterate over source and affect its sub values into destination, recursively.
|
|
1105
|
+
* If the source and destination can't be merged, return source.
|
|
1106
|
+
*/
|
|
1107
|
+
export function mergeInto(
|
|
1108
|
+
destination,
|
|
1109
|
+
source,
|
|
1110
|
+
circularReferenceChecker
|
|
1111
|
+
) {
|
|
1112
|
+
// ignore the source if it is undefined
|
|
1113
|
+
if (typeof circularReferenceChecker === 'undefined') {
|
|
1114
|
+
circularReferenceChecker = createCircularReferenceChecker()
|
|
1115
|
+
}
|
|
1116
|
+
if (source === undefined) {
|
|
1117
|
+
return destination
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
if (typeof source !== 'object' || source === null) {
|
|
1121
|
+
// primitive values - just return source
|
|
1122
|
+
return source
|
|
1123
|
+
} else if (source instanceof Date) {
|
|
1124
|
+
return new Date(source.getTime())
|
|
1125
|
+
} else if (source instanceof RegExp) {
|
|
1126
|
+
var flags =
|
|
1127
|
+
source.flags ||
|
|
1128
|
+
// old browsers compatibility
|
|
1129
|
+
[
|
|
1130
|
+
source.global ? 'g' : '',
|
|
1131
|
+
source.ignoreCase ? 'i' : '',
|
|
1132
|
+
source.multiline ? 'm' : '',
|
|
1133
|
+
source.sticky ? 'y' : '',
|
|
1134
|
+
source.unicode ? 'u' : '',
|
|
1135
|
+
].join('')
|
|
1136
|
+
return new RegExp(source.source, flags)
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1139
|
+
if (circularReferenceChecker.hasAlreadyBeenSeen(source)) {
|
|
1140
|
+
// remove circular references
|
|
1141
|
+
return undefined
|
|
1142
|
+
} else if (Array.isArray(source)) {
|
|
1143
|
+
var merged= Array.isArray(destination) ? destination : []
|
|
1144
|
+
for (var i = 0; i < source.length; ++i) {
|
|
1145
|
+
merged[i] = mergeInto(merged[i], source[i], circularReferenceChecker)
|
|
1146
|
+
}
|
|
1147
|
+
return merged
|
|
1148
|
+
}
|
|
1149
|
+
|
|
1150
|
+
var merged = getType(destination) === 'object' ? destination : {}
|
|
1151
|
+
for (var key in source) {
|
|
1152
|
+
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
1153
|
+
merged[key] = mergeInto(merged[key], source[key], circularReferenceChecker)
|
|
1154
|
+
}
|
|
1155
|
+
}
|
|
1156
|
+
return merged
|
|
1157
|
+
}
|
|
1067
1158
|
|
|
1159
|
+
/**
|
|
1160
|
+
* A simplistic implementation of a deep clone algorithm.
|
|
1161
|
+
* Caveats:
|
|
1162
|
+
* - It doesn't maintain prototype chains - don't use with instances of custom classes.
|
|
1163
|
+
* - It doesn't handle Map and Set
|
|
1164
|
+
*/
|
|
1165
|
+
export function deepClone(value){
|
|
1166
|
+
return mergeInto(undefined, value)
|
|
1167
|
+
}
|
|
1068
1168
|
export var _URL = function (url) {
|
|
1069
1169
|
var result = {}
|
|
1070
1170
|
var basicProps = [
|