@newtalaria/browser 0.1.17 → 0.1.19
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/README.md +136 -15
- package/dist/client.d.ts +13 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +628 -37
- package/dist/index.js.map +4 -4
- package/dist/replay/hooks.d.ts +45 -2
- package/dist/replay/hooks.d.ts.map +1 -1
- package/dist/replay/privacy.d.ts +1 -1
- package/dist/replay/privacy.d.ts.map +1 -1
- package/dist/sdk_meta.d.ts +1 -1
- package/dist/talaria.browser.iife.js +610 -36
- package/dist/talaria.browser.iife.js.map +4 -4
- package/dist/transport/events.d.ts +4 -1
- package/dist/transport/events.d.ts.map +1 -1
- package/dist/types.d.ts +112 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/browser_context.d.ts +4 -3
- package/dist/utils/browser_context.d.ts.map +1 -1
- package/dist/utils/network_error.d.ts +5 -0
- package/dist/utils/network_error.d.ts.map +1 -1
- package/dist/utils/stacktrace.d.ts +35 -0
- package/dist/utils/stacktrace.d.ts.map +1 -0
- package/dist/utils/tags.d.ts +28 -0
- package/dist/utils/tags.d.ts.map +1 -0
- package/package.json +1 -1
|
@@ -272,9 +272,253 @@
|
|
|
272
272
|
return base;
|
|
273
273
|
}
|
|
274
274
|
|
|
275
|
+
// src/utils/tags.ts
|
|
276
|
+
var MAX_TAGS_PER_EVENT = 20;
|
|
277
|
+
var MAX_TAG_KEY_LENGTH = 64;
|
|
278
|
+
var MAX_TAG_VALUE_LENGTH = 128;
|
|
279
|
+
var MAX_TAG_TOTAL_UTF8_BYTES = 2048;
|
|
280
|
+
var KEY_PATTERN = /^[a-z0-9_.-]+$/;
|
|
281
|
+
var HIGH_CARDINALITY_TAG_KEYS = /* @__PURE__ */ new Set([
|
|
282
|
+
"user_id",
|
|
283
|
+
"userid",
|
|
284
|
+
"request_id",
|
|
285
|
+
"requestid",
|
|
286
|
+
"business_id",
|
|
287
|
+
"order_id",
|
|
288
|
+
"email",
|
|
289
|
+
"url",
|
|
290
|
+
"uuid",
|
|
291
|
+
"session_id",
|
|
292
|
+
"trace_id",
|
|
293
|
+
"span_id"
|
|
294
|
+
]);
|
|
295
|
+
var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
296
|
+
var EMAIL_RE = /^[^@\s]+@[^@\s]+\.[^@\s]+$/;
|
|
297
|
+
var LONG_NUMERIC_RE = /^\d{8,}$/;
|
|
298
|
+
function utf8Bytes(s) {
|
|
299
|
+
if (typeof TextEncoder !== "undefined") {
|
|
300
|
+
return new TextEncoder().encode(s).length;
|
|
301
|
+
}
|
|
302
|
+
return unescape(encodeURIComponent(s)).length;
|
|
303
|
+
}
|
|
304
|
+
function normalizeKey(raw) {
|
|
305
|
+
const key = raw.trim().toLowerCase();
|
|
306
|
+
if (!key || key.length > MAX_TAG_KEY_LENGTH) return null;
|
|
307
|
+
if (!KEY_PATTERN.test(key)) return null;
|
|
308
|
+
return key;
|
|
309
|
+
}
|
|
310
|
+
function normalizeValue(raw) {
|
|
311
|
+
if (raw == null) return null;
|
|
312
|
+
const value = String(raw).trim();
|
|
313
|
+
if (!value) return null;
|
|
314
|
+
return value.length <= MAX_TAG_VALUE_LENGTH ? value : value.slice(0, MAX_TAG_VALUE_LENGTH);
|
|
315
|
+
}
|
|
316
|
+
function normalizeTags(tags) {
|
|
317
|
+
if (!tags) return {};
|
|
318
|
+
const result2 = {};
|
|
319
|
+
let totalBytes = 0;
|
|
320
|
+
for (const [rawKey, rawValue] of Object.entries(tags)) {
|
|
321
|
+
if (Object.keys(result2).length >= MAX_TAGS_PER_EVENT) break;
|
|
322
|
+
const key = normalizeKey(rawKey);
|
|
323
|
+
if (!key) continue;
|
|
324
|
+
const value = normalizeValue(rawValue);
|
|
325
|
+
if (value == null) continue;
|
|
326
|
+
if (result2[key] != null) {
|
|
327
|
+
totalBytes -= utf8Bytes(key) + utf8Bytes(result2[key]);
|
|
328
|
+
}
|
|
329
|
+
const entryBytes = utf8Bytes(key) + utf8Bytes(value);
|
|
330
|
+
if (totalBytes + entryBytes > MAX_TAG_TOTAL_UTF8_BYTES) continue;
|
|
331
|
+
result2[key] = value;
|
|
332
|
+
totalBytes += entryBytes;
|
|
333
|
+
}
|
|
334
|
+
return result2;
|
|
335
|
+
}
|
|
336
|
+
function mergeTags(...parts) {
|
|
337
|
+
const merged = {};
|
|
338
|
+
for (const part of parts) {
|
|
339
|
+
if (!part) continue;
|
|
340
|
+
Object.assign(merged, part);
|
|
341
|
+
}
|
|
342
|
+
return normalizeTags(merged);
|
|
343
|
+
}
|
|
344
|
+
function looksHighCardinalityValue(value) {
|
|
345
|
+
return UUID_RE.test(value) || EMAIL_RE.test(value) || LONG_NUMERIC_RE.test(value);
|
|
346
|
+
}
|
|
347
|
+
function warnSuspiciousTags(tags, environment) {
|
|
348
|
+
if (!environment || environment === "production") return;
|
|
349
|
+
if (typeof console === "undefined" || typeof console.warn !== "function") {
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
for (const [key, value] of Object.entries(tags)) {
|
|
353
|
+
if (HIGH_CARDINALITY_TAG_KEYS.has(key)) {
|
|
354
|
+
console.warn(
|
|
355
|
+
`@newtalaria/browser: Tag "${key}" appears to have high cardinality. Consider moving it to context/extra.`
|
|
356
|
+
);
|
|
357
|
+
continue;
|
|
358
|
+
}
|
|
359
|
+
if (looksHighCardinalityValue(value)) {
|
|
360
|
+
console.warn(
|
|
361
|
+
`@newtalaria/browser: Tag "${key}" value looks high-cardinality. Consider moving it to context/extra.`
|
|
362
|
+
);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
// src/utils/stacktrace.ts
|
|
368
|
+
var V8_FRAME = /^\s*at\s+(?:(.+?)\s+\()?(.+?):(\d+):(\d+)\)?\s*$/;
|
|
369
|
+
var V8_FRAME_BARE = /^\s*at\s+(.+)\s*$/;
|
|
370
|
+
var EXTENSION_URL2 = /(?:chrome|moz|safari|safari-web|ms-browser)-extension:\/\//i;
|
|
371
|
+
function parseStackTrace(stack, inAppOptions) {
|
|
372
|
+
if (!stack || !stack.trim()) return void 0;
|
|
373
|
+
const parsed = [];
|
|
374
|
+
for (const line of stack.split("\n")) {
|
|
375
|
+
const frame = parseStackLine(line, inAppOptions);
|
|
376
|
+
if (frame) parsed.push(frame);
|
|
377
|
+
}
|
|
378
|
+
if (parsed.length === 0) return void 0;
|
|
379
|
+
parsed.reverse();
|
|
380
|
+
return { frames: parsed };
|
|
381
|
+
}
|
|
382
|
+
function parseStackLine(line, inAppOptions) {
|
|
383
|
+
if (!/^\s*at\s+/.test(line)) return null;
|
|
384
|
+
const v8 = V8_FRAME.exec(line);
|
|
385
|
+
if (v8) {
|
|
386
|
+
const functionName = cleanFunction(v8[1]);
|
|
387
|
+
const absPath = stripQuery(v8[2] ?? "");
|
|
388
|
+
const lineno = Number.parseInt(v8[3] ?? "", 10);
|
|
389
|
+
const colno = Number.parseInt(v8[4] ?? "", 10);
|
|
390
|
+
return {
|
|
391
|
+
functionName,
|
|
392
|
+
absPath: absPath || void 0,
|
|
393
|
+
filename: basename(absPath),
|
|
394
|
+
lineno: Number.isFinite(lineno) ? lineno : void 0,
|
|
395
|
+
colno: Number.isFinite(colno) ? colno : void 0,
|
|
396
|
+
inApp: isInAppFrame(absPath, inAppOptions),
|
|
397
|
+
platform: "javascript"
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
const bare = V8_FRAME_BARE.exec(line);
|
|
401
|
+
if (bare) {
|
|
402
|
+
const functionName = cleanFunction(bare[1]);
|
|
403
|
+
if (!functionName) return null;
|
|
404
|
+
return {
|
|
405
|
+
functionName,
|
|
406
|
+
inApp: false,
|
|
407
|
+
platform: "javascript"
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
return null;
|
|
411
|
+
}
|
|
412
|
+
function applySourceLocation(stacktrace, source, inAppOptions) {
|
|
413
|
+
if (!source) return stacktrace;
|
|
414
|
+
const filename = source.filename?.trim() || void 0;
|
|
415
|
+
const lineno = typeof source.lineno === "number" && source.lineno > 0 ? source.lineno : void 0;
|
|
416
|
+
const colno = typeof source.colno === "number" && source.colno >= 0 ? source.colno : void 0;
|
|
417
|
+
if (!filename && lineno == null && colno == null) return stacktrace;
|
|
418
|
+
if (!stacktrace || stacktrace.frames.length === 0) {
|
|
419
|
+
if (!filename && lineno == null) return stacktrace;
|
|
420
|
+
const absPath = filename;
|
|
421
|
+
return {
|
|
422
|
+
frames: [
|
|
423
|
+
{
|
|
424
|
+
filename: absPath ? basename(absPath) : void 0,
|
|
425
|
+
absPath,
|
|
426
|
+
lineno,
|
|
427
|
+
colno,
|
|
428
|
+
inApp: absPath ? isInAppFrame(absPath, inAppOptions) : true,
|
|
429
|
+
platform: "javascript"
|
|
430
|
+
}
|
|
431
|
+
]
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
const frames = stacktrace.frames.slice();
|
|
435
|
+
const top = { ...frames[frames.length - 1] };
|
|
436
|
+
if (filename) {
|
|
437
|
+
top.absPath = filename;
|
|
438
|
+
top.filename = basename(filename);
|
|
439
|
+
top.inApp = isInAppFrame(filename, inAppOptions);
|
|
440
|
+
}
|
|
441
|
+
if (lineno != null) top.lineno = lineno;
|
|
442
|
+
if (colno != null) top.colno = colno;
|
|
443
|
+
frames[frames.length - 1] = top;
|
|
444
|
+
return { ...stacktrace, frames };
|
|
445
|
+
}
|
|
446
|
+
function isInAppFrame(path, options) {
|
|
447
|
+
const lower = path.toLowerCase();
|
|
448
|
+
if (!lower) return true;
|
|
449
|
+
if (lower.includes("node_modules")) return false;
|
|
450
|
+
if (EXTENSION_URL2.test(path) || lower.includes("webkit-masked-url://")) {
|
|
451
|
+
return false;
|
|
452
|
+
}
|
|
453
|
+
if (lower.includes("@newtalaria/browser")) return false;
|
|
454
|
+
if (matchesUrlList(path, options?.denyUrls)) return false;
|
|
455
|
+
if (matchesUrlList(path, options?.allowUrls)) return true;
|
|
456
|
+
const frameOrigin = tryParseOrigin(path);
|
|
457
|
+
if (frameOrigin != null) {
|
|
458
|
+
const pageOrigin = normalizeOrigin(options?.pageOrigin);
|
|
459
|
+
if (pageOrigin && frameOrigin === pageOrigin) return true;
|
|
460
|
+
const extra = options?.inAppOrigins ?? [];
|
|
461
|
+
for (const origin of extra) {
|
|
462
|
+
if (normalizeOrigin(origin) === frameOrigin) return true;
|
|
463
|
+
}
|
|
464
|
+
return false;
|
|
465
|
+
}
|
|
466
|
+
return true;
|
|
467
|
+
}
|
|
468
|
+
function matchesUrlList(path, patterns) {
|
|
469
|
+
if (!patterns || patterns.length === 0) return false;
|
|
470
|
+
for (const pattern of patterns) {
|
|
471
|
+
if (typeof pattern === "string") {
|
|
472
|
+
if (pattern && path.includes(pattern)) return true;
|
|
473
|
+
} else if (pattern.test(path)) {
|
|
474
|
+
return true;
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
return false;
|
|
478
|
+
}
|
|
479
|
+
function tryParseOrigin(path) {
|
|
480
|
+
if (!/^https?:\/\//i.test(path)) return null;
|
|
481
|
+
try {
|
|
482
|
+
return new URL(path).origin;
|
|
483
|
+
} catch {
|
|
484
|
+
return null;
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
function normalizeOrigin(origin) {
|
|
488
|
+
if (!origin || !origin.trim()) return null;
|
|
489
|
+
const trimmed = origin.trim();
|
|
490
|
+
try {
|
|
491
|
+
if (/^https?:\/\//i.test(trimmed)) {
|
|
492
|
+
return new URL(trimmed).origin;
|
|
493
|
+
}
|
|
494
|
+
return trimmed;
|
|
495
|
+
} catch {
|
|
496
|
+
return trimmed;
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
function resolvePageOrigin(originOrUrl) {
|
|
500
|
+
return normalizeOrigin(originOrUrl) ?? void 0;
|
|
501
|
+
}
|
|
502
|
+
function cleanFunction(raw) {
|
|
503
|
+
if (raw == null) return void 0;
|
|
504
|
+
const value = raw.trim();
|
|
505
|
+
return value.length === 0 ? void 0 : value;
|
|
506
|
+
}
|
|
507
|
+
function stripQuery(path) {
|
|
508
|
+
const q = path.indexOf("?");
|
|
509
|
+
return q >= 0 ? path.slice(0, q) : path;
|
|
510
|
+
}
|
|
511
|
+
function basename(path) {
|
|
512
|
+
if (!path) return void 0;
|
|
513
|
+
const normalized = stripQuery(path);
|
|
514
|
+
const parts = normalized.split(/[/\\]/);
|
|
515
|
+
const last = parts[parts.length - 1];
|
|
516
|
+
return last || normalized;
|
|
517
|
+
}
|
|
518
|
+
|
|
275
519
|
// src/sdk_meta.ts
|
|
276
520
|
var SDK_NAME = "@newtalaria/browser";
|
|
277
|
-
var SDK_VERSION = "0.1.
|
|
521
|
+
var SDK_VERSION = "0.1.18";
|
|
278
522
|
|
|
279
523
|
// src/transport/serverpod.ts
|
|
280
524
|
var ServerpodTransport = class {
|
|
@@ -332,6 +576,9 @@
|
|
|
332
576
|
if (params.eventType) input2.eventType = params.eventType;
|
|
333
577
|
if (params.title) input2.title = params.title;
|
|
334
578
|
if (params.stackTrace) input2.stackTrace = params.stackTrace;
|
|
579
|
+
if (params.exception) input2.exception = serializeException(params.exception);
|
|
580
|
+
if (params.debugMeta) input2.debugMeta = serializeDebugMeta(params.debugMeta);
|
|
581
|
+
if (params.platform) input2.platform = params.platform;
|
|
335
582
|
if (params.release) input2.release = params.release;
|
|
336
583
|
if (params.userId) input2.userId = params.userId;
|
|
337
584
|
if (params.sessionId) input2.sessionId = params.sessionId;
|
|
@@ -348,6 +595,89 @@
|
|
|
348
595
|
{ keepalive: params.keepalive }
|
|
349
596
|
);
|
|
350
597
|
}
|
|
598
|
+
function serializeException(data) {
|
|
599
|
+
return {
|
|
600
|
+
__className__: "ExceptionDataDto",
|
|
601
|
+
values: data.values.map(serializeExceptionValue)
|
|
602
|
+
};
|
|
603
|
+
}
|
|
604
|
+
function serializeExceptionValue(value) {
|
|
605
|
+
const out = {
|
|
606
|
+
__className__: "ExceptionValueDto"
|
|
607
|
+
};
|
|
608
|
+
if (value.type != null) out.type = value.type;
|
|
609
|
+
if (value.value != null) out.value = value.value;
|
|
610
|
+
if (value.module != null) out.module = value.module;
|
|
611
|
+
if (value.threadId != null) out.threadId = value.threadId;
|
|
612
|
+
if (value.code != null) out.code = value.code;
|
|
613
|
+
if (value.mechanism) out.mechanism = serializeMechanism(value.mechanism);
|
|
614
|
+
if (value.stacktrace) out.stacktrace = serializeStackTrace(value.stacktrace);
|
|
615
|
+
return out;
|
|
616
|
+
}
|
|
617
|
+
function serializeMechanism(mechanism) {
|
|
618
|
+
const out = {
|
|
619
|
+
__className__: "ExceptionMechanismDto",
|
|
620
|
+
type: mechanism.type
|
|
621
|
+
};
|
|
622
|
+
if (mechanism.handled != null) out.handled = mechanism.handled;
|
|
623
|
+
if (mechanism.synthetic != null) out.synthetic = mechanism.synthetic;
|
|
624
|
+
return out;
|
|
625
|
+
}
|
|
626
|
+
function serializeStackTrace(stack) {
|
|
627
|
+
const out = {
|
|
628
|
+
__className__: "StackTraceDto",
|
|
629
|
+
frames: stack.frames.map(serializeStackFrame)
|
|
630
|
+
};
|
|
631
|
+
if (stack.registers) out.registers = stack.registers;
|
|
632
|
+
return out;
|
|
633
|
+
}
|
|
634
|
+
function serializeStackFrame(frame) {
|
|
635
|
+
const out = {
|
|
636
|
+
__className__: "StackFrameDto"
|
|
637
|
+
};
|
|
638
|
+
if (frame.filename != null) out.filename = frame.filename;
|
|
639
|
+
if (frame.absPath != null) out.absPath = frame.absPath;
|
|
640
|
+
if (frame.functionName != null) out.functionName = frame.functionName;
|
|
641
|
+
if (frame.rawFunction != null) out.rawFunction = frame.rawFunction;
|
|
642
|
+
if (frame.module != null) out.module = frame.module;
|
|
643
|
+
if (frame.package != null) out.package = frame.package;
|
|
644
|
+
if (frame.platform != null) out.platform = frame.platform;
|
|
645
|
+
if (frame.lineno != null) out.lineno = frame.lineno;
|
|
646
|
+
if (frame.colno != null) out.colno = frame.colno;
|
|
647
|
+
if (frame.inApp != null) out.inApp = frame.inApp;
|
|
648
|
+
if (frame.instructionAddr != null) out.instructionAddr = frame.instructionAddr;
|
|
649
|
+
if (frame.symbolAddr != null) out.symbolAddr = frame.symbolAddr;
|
|
650
|
+
if (frame.imageAddr != null) out.imageAddr = frame.imageAddr;
|
|
651
|
+
if (frame.addrMode != null) out.addrMode = frame.addrMode;
|
|
652
|
+
if (frame.contextLine != null) out.contextLine = frame.contextLine;
|
|
653
|
+
if (frame.preContext != null) out.preContext = frame.preContext;
|
|
654
|
+
if (frame.postContext != null) out.postContext = frame.postContext;
|
|
655
|
+
if (frame.vars != null) out.vars = frame.vars;
|
|
656
|
+
if (frame.stackStart != null) out.stackStart = frame.stackStart;
|
|
657
|
+
return out;
|
|
658
|
+
}
|
|
659
|
+
function serializeDebugMeta(meta) {
|
|
660
|
+
const out = {
|
|
661
|
+
__className__: "DebugMetaDto"
|
|
662
|
+
};
|
|
663
|
+
if (meta.images) {
|
|
664
|
+
out.images = meta.images.map((image) => {
|
|
665
|
+
const img = {
|
|
666
|
+
__className__: "DebugImageDto"
|
|
667
|
+
};
|
|
668
|
+
if (image.type != null) img.type = image.type;
|
|
669
|
+
if (image.imageAddr != null) img.imageAddr = image.imageAddr;
|
|
670
|
+
if (image.imageSize != null) img.imageSize = image.imageSize;
|
|
671
|
+
if (image.debugId != null) img.debugId = image.debugId;
|
|
672
|
+
if (image.debugFile != null) img.debugFile = image.debugFile;
|
|
673
|
+
if (image.codeId != null) img.codeId = image.codeId;
|
|
674
|
+
if (image.codeFile != null) img.codeFile = image.codeFile;
|
|
675
|
+
if (image.arch != null) img.arch = image.arch;
|
|
676
|
+
return img;
|
|
677
|
+
});
|
|
678
|
+
}
|
|
679
|
+
return out;
|
|
680
|
+
}
|
|
351
681
|
|
|
352
682
|
// src/utils/gzip.ts
|
|
353
683
|
async function gzipBytes(data) {
|
|
@@ -13484,18 +13814,22 @@
|
|
|
13484
13814
|
var { takeFullSnapshot } = record;
|
|
13485
13815
|
|
|
13486
13816
|
// src/replay/privacy.ts
|
|
13487
|
-
var
|
|
13817
|
+
var SENSITIVE_QUERY_KEY = /^(?:token|secret|password|auth|api[_-]?key|access[_-]?token|gclid|fbclid|gcl_au|msclkid|_ga(?:_.*)?|cid|sid)$/i;
|
|
13818
|
+
var SENSITIVE_QUERY_LEGACY = /(?:^|[?&])(token|secret|password|auth|api[_-]?key|access[_-]?token|gclid|fbclid|gcl_au|msclkid|_ga(?:_[^=&#]*)?|cid|sid)=([^&#]*)/gi;
|
|
13819
|
+
function isSensitiveQueryKey(key) {
|
|
13820
|
+
return SENSITIVE_QUERY_KEY.test(key);
|
|
13821
|
+
}
|
|
13488
13822
|
function redactUrl(raw) {
|
|
13489
13823
|
try {
|
|
13490
13824
|
const url = new URL(raw, typeof location !== "undefined" ? location.href : void 0);
|
|
13491
13825
|
for (const key of [...url.searchParams.keys()]) {
|
|
13492
|
-
if (
|
|
13826
|
+
if (isSensitiveQueryKey(key)) {
|
|
13493
13827
|
url.searchParams.set(key, "[Filtered]");
|
|
13494
13828
|
}
|
|
13495
13829
|
}
|
|
13496
13830
|
return url.toString();
|
|
13497
13831
|
} catch {
|
|
13498
|
-
return raw.replace(
|
|
13832
|
+
return raw.replace(SENSITIVE_QUERY_LEGACY, (_m, name) => `${name}=[Filtered]`);
|
|
13499
13833
|
}
|
|
13500
13834
|
}
|
|
13501
13835
|
function sanitizeNetworkUrl(raw, opts) {
|
|
@@ -13592,6 +13926,9 @@
|
|
|
13592
13926
|
function isAbortError(error) {
|
|
13593
13927
|
return error instanceof Error && error.name === "AbortError";
|
|
13594
13928
|
}
|
|
13929
|
+
function isTimeoutError(error) {
|
|
13930
|
+
return error instanceof Error && error.name === "TimeoutError";
|
|
13931
|
+
}
|
|
13595
13932
|
function isLikelyNetworkFetchError(error) {
|
|
13596
13933
|
if (!(error instanceof Error)) return false;
|
|
13597
13934
|
if (error.name === "AbortError" || error.name === "TimeoutError") return false;
|
|
@@ -13599,6 +13936,9 @@
|
|
|
13599
13936
|
const msg = error.message.toLowerCase().trim();
|
|
13600
13937
|
return msg === "failed to fetch" || msg === "load failed" || msg === "networkerror when attempting to fetch resource." || msg.startsWith("networkerror") || msg.includes("failed to fetch");
|
|
13601
13938
|
}
|
|
13939
|
+
function isCorrelatableTransportError(error) {
|
|
13940
|
+
return isLikelyNetworkFetchError(error) || isTimeoutError(error);
|
|
13941
|
+
}
|
|
13602
13942
|
function describeUnknownError(error) {
|
|
13603
13943
|
if (error instanceof Error) {
|
|
13604
13944
|
return {
|
|
@@ -13746,6 +14086,56 @@
|
|
|
13746
14086
|
}
|
|
13747
14087
|
return false;
|
|
13748
14088
|
}
|
|
14089
|
+
function normalizeNetworkOrigin(raw) {
|
|
14090
|
+
const trimmed = (raw || "").trim();
|
|
14091
|
+
if (!trimmed || trimmed === "*") return trimmed;
|
|
14092
|
+
try {
|
|
14093
|
+
return new URL(trimmed).origin;
|
|
14094
|
+
} catch {
|
|
14095
|
+
try {
|
|
14096
|
+
return new URL(`https://${trimmed}`).origin;
|
|
14097
|
+
} catch {
|
|
14098
|
+
return trimmed.replace(/\/+$/, "");
|
|
14099
|
+
}
|
|
14100
|
+
}
|
|
14101
|
+
}
|
|
14102
|
+
function resolvePageOrigin2(pageOrigin) {
|
|
14103
|
+
if (pageOrigin) {
|
|
14104
|
+
try {
|
|
14105
|
+
return new URL(pageOrigin).origin;
|
|
14106
|
+
} catch {
|
|
14107
|
+
return pageOrigin.replace(/\/+$/, "");
|
|
14108
|
+
}
|
|
14109
|
+
}
|
|
14110
|
+
if (typeof location !== "undefined" && location.origin) {
|
|
14111
|
+
return location.origin;
|
|
14112
|
+
}
|
|
14113
|
+
return "";
|
|
14114
|
+
}
|
|
14115
|
+
function resolveRequestOrigin(rawUrl, pageOrigin) {
|
|
14116
|
+
const base = pageOrigin || (typeof location !== "undefined" ? location.href : void 0);
|
|
14117
|
+
try {
|
|
14118
|
+
return new URL(rawUrl, base).origin;
|
|
14119
|
+
} catch {
|
|
14120
|
+
return "";
|
|
14121
|
+
}
|
|
14122
|
+
}
|
|
14123
|
+
function isAllowedNetworkOrigin(requestOrigin, opts) {
|
|
14124
|
+
if (!requestOrigin) return false;
|
|
14125
|
+
const allow = opts.networkErrorOrigins.map(normalizeNetworkOrigin);
|
|
14126
|
+
if (allow.includes("*")) return true;
|
|
14127
|
+
const page = resolvePageOrigin2(opts.pageOrigin);
|
|
14128
|
+
if (page && requestOrigin === page) return true;
|
|
14129
|
+
return allow.includes(requestOrigin);
|
|
14130
|
+
}
|
|
14131
|
+
function classifyNetworkParty(requestOrigin, pageOrigin) {
|
|
14132
|
+
const page = resolvePageOrigin2(pageOrigin);
|
|
14133
|
+
if (page && requestOrigin && requestOrigin === page) return "first_party";
|
|
14134
|
+
return "third_party";
|
|
14135
|
+
}
|
|
14136
|
+
function isHttpOkStatus(status) {
|
|
14137
|
+
return status >= 200 && status < 300;
|
|
14138
|
+
}
|
|
13749
14139
|
function shouldPromoteFailedRequest(meta, opts) {
|
|
13750
14140
|
if (!opts.captureFailedRequests) return false;
|
|
13751
14141
|
if (typeof meta.status !== "number" || Number.isNaN(meta.status)) return false;
|
|
@@ -13756,6 +14146,13 @@
|
|
|
13756
14146
|
opts.talariaBaseUrl
|
|
13757
14147
|
);
|
|
13758
14148
|
if (urlMatchesIgnoreList(meta.url || "", ignore)) return false;
|
|
14149
|
+
const requestOrigin = meta.origin || resolveRequestOrigin(meta.url || "", opts.pageOrigin);
|
|
14150
|
+
if (!isAllowedNetworkOrigin(requestOrigin, {
|
|
14151
|
+
networkErrorOrigins: opts.networkErrorOrigins ?? [],
|
|
14152
|
+
pageOrigin: opts.pageOrigin
|
|
14153
|
+
})) {
|
|
14154
|
+
return false;
|
|
14155
|
+
}
|
|
13759
14156
|
return true;
|
|
13760
14157
|
}
|
|
13761
14158
|
function shouldPromoteNetworkError(meta, opts) {
|
|
@@ -13769,6 +14166,13 @@
|
|
|
13769
14166
|
opts.talariaBaseUrl
|
|
13770
14167
|
);
|
|
13771
14168
|
if (urlMatchesIgnoreList(meta.url || "", ignore)) return false;
|
|
14169
|
+
const requestOrigin = meta.origin || resolveRequestOrigin(meta.url || "", opts.pageOrigin);
|
|
14170
|
+
if (!isAllowedNetworkOrigin(requestOrigin, {
|
|
14171
|
+
networkErrorOrigins: opts.networkErrorOrigins ?? [],
|
|
14172
|
+
pageOrigin: opts.pageOrigin
|
|
14173
|
+
})) {
|
|
14174
|
+
return false;
|
|
14175
|
+
}
|
|
13772
14176
|
return true;
|
|
13773
14177
|
}
|
|
13774
14178
|
function enrichNetworkMeta(meta) {
|
|
@@ -13779,7 +14183,8 @@
|
|
|
13779
14183
|
failureKind: meta.ok === false ? "http" : meta.failureKind
|
|
13780
14184
|
};
|
|
13781
14185
|
}
|
|
13782
|
-
|
|
14186
|
+
const hasTransportSignal = !!meta.errorName || !!meta.errorMessage || !!meta.aborted || meta.failureKind === "abort" || meta.failureKind === "timeout" || meta.failureKind === "network";
|
|
14187
|
+
if (hasTransportSignal) {
|
|
13783
14188
|
const failureKind = meta.failureKind === "abort" || meta.failureKind === "timeout" || meta.failureKind === "network" ? meta.failureKind : classifyTransportFailure({
|
|
13784
14189
|
aborted: meta.aborted,
|
|
13785
14190
|
errorName: meta.errorName
|
|
@@ -13792,10 +14197,13 @@
|
|
|
13792
14197
|
}
|
|
13793
14198
|
return meta;
|
|
13794
14199
|
}
|
|
13795
|
-
function networkUrlParts(rawUrl, includeQuery) {
|
|
13796
|
-
const
|
|
14200
|
+
function networkUrlParts(rawUrl, includeQuery, pageOrigin) {
|
|
14201
|
+
const baseHref = pageOrigin || (typeof location !== "undefined" ? location.href : void 0);
|
|
14202
|
+
const parts = sanitizeNetworkUrl(rawUrl, { includeQuery, baseHref });
|
|
14203
|
+
const origin = resolveRequestOrigin(rawUrl, pageOrigin);
|
|
13797
14204
|
return {
|
|
13798
14205
|
url: parts.url,
|
|
14206
|
+
origin: origin || void 0,
|
|
13799
14207
|
hostname: parts.hostname,
|
|
13800
14208
|
pathname: parts.pathname,
|
|
13801
14209
|
...parts.search ? { search: parts.search } : {}
|
|
@@ -13811,14 +14219,22 @@
|
|
|
13811
14219
|
captureNetworkErrors: options.captureNetworkErrors ?? true,
|
|
13812
14220
|
failedRequestStatusCodes: options.failedRequestStatusCodes ?? [[500, 599]],
|
|
13813
14221
|
failedRequestIgnoreUrls: options.failedRequestIgnoreUrls ?? [],
|
|
14222
|
+
networkErrorOrigins: options.networkErrorOrigins ?? [],
|
|
14223
|
+
pageOrigin: options.pageOrigin,
|
|
13814
14224
|
talariaBaseUrl: options.talariaBaseUrl
|
|
13815
14225
|
};
|
|
13816
14226
|
const includeQuery = options.captureRequestQueryParameters ?? options.includeNetworkUrlQuery ?? false;
|
|
13817
14227
|
const handleMeta = (meta) => {
|
|
13818
14228
|
const { rawUrl, ...rest } = meta;
|
|
14229
|
+
const parts = networkUrlParts(rawUrl, includeQuery, matchOpts.pageOrigin);
|
|
14230
|
+
const party = classifyNetworkParty(
|
|
14231
|
+
parts.origin || "",
|
|
14232
|
+
matchOpts.pageOrigin
|
|
14233
|
+
);
|
|
13819
14234
|
const enriched = enrichNetworkMeta({
|
|
13820
14235
|
...rest,
|
|
13821
|
-
...
|
|
14236
|
+
...parts,
|
|
14237
|
+
party
|
|
13822
14238
|
});
|
|
13823
14239
|
try {
|
|
13824
14240
|
emitNetwork(enriched);
|
|
@@ -13838,6 +14254,7 @@
|
|
|
13838
14254
|
const rawUrl = typeof input2 === "string" ? input2 : input2 instanceof URL ? input2.toString() : input2.url;
|
|
13839
14255
|
try {
|
|
13840
14256
|
const response = await originalFetch(input2, init);
|
|
14257
|
+
const opaque = response.type === "opaque" || response.type === "opaqueredirect";
|
|
13841
14258
|
handleMeta({
|
|
13842
14259
|
method,
|
|
13843
14260
|
rawUrl,
|
|
@@ -13845,7 +14262,8 @@
|
|
|
13845
14262
|
transport: "fetch",
|
|
13846
14263
|
status: response.status,
|
|
13847
14264
|
durationMs: Date.now() - started,
|
|
13848
|
-
|
|
14265
|
+
// Opaque responses resolve successfully with status 0 — not a failure.
|
|
14266
|
+
ok: opaque ? true : response.ok
|
|
13849
14267
|
});
|
|
13850
14268
|
return response;
|
|
13851
14269
|
} catch (error) {
|
|
@@ -13907,7 +14325,7 @@
|
|
|
13907
14325
|
transport: "xhr",
|
|
13908
14326
|
status,
|
|
13909
14327
|
durationMs: Date.now() - (this.__talariaStarted ?? Date.now()),
|
|
13910
|
-
ok: status
|
|
14328
|
+
ok: isHttpOkStatus(status),
|
|
13911
14329
|
...transportFail ? {
|
|
13912
14330
|
failureKind,
|
|
13913
14331
|
errorName,
|
|
@@ -13916,7 +14334,7 @@
|
|
|
13916
14334
|
} : {}
|
|
13917
14335
|
});
|
|
13918
14336
|
};
|
|
13919
|
-
this.addEventListener("loadend", onDone);
|
|
14337
|
+
this.addEventListener("loadend", onDone, { once: true });
|
|
13920
14338
|
return originalSend.call(this, body);
|
|
13921
14339
|
};
|
|
13922
14340
|
}
|
|
@@ -13928,10 +14346,26 @@
|
|
|
13928
14346
|
}
|
|
13929
14347
|
|
|
13930
14348
|
// src/client.ts
|
|
14349
|
+
var PLATFORM_JAVASCRIPT = "javascript";
|
|
14350
|
+
var EXTRA_LOCATION_KEYS = /* @__PURE__ */ new Set([
|
|
14351
|
+
"exception_class",
|
|
14352
|
+
"file",
|
|
14353
|
+
"line",
|
|
14354
|
+
"code",
|
|
14355
|
+
"filename",
|
|
14356
|
+
"lineno",
|
|
14357
|
+
"colno"
|
|
14358
|
+
]);
|
|
14359
|
+
function networkExceptionClass(failure) {
|
|
14360
|
+
if (failure.failureKind === "http") return "HttpError";
|
|
14361
|
+
if (failure.failureKind === "timeout") return "TimeoutError";
|
|
14362
|
+
return "NetworkError";
|
|
14363
|
+
}
|
|
13931
14364
|
function networkFailureTags(failure) {
|
|
13932
14365
|
return {
|
|
13933
14366
|
"http.method": failure.method || "GET",
|
|
13934
14367
|
"network.failure_kind": failure.failureKind ?? "network",
|
|
14368
|
+
...failure.party ? { "network.party": failure.party } : {},
|
|
13935
14369
|
...failure.transport ? { "network.transport": failure.transport } : {},
|
|
13936
14370
|
...failure.errorName ? { "network.error_name": failure.errorName } : {}
|
|
13937
14371
|
};
|
|
@@ -13941,6 +14375,7 @@
|
|
|
13941
14375
|
method: failure.method || "GET",
|
|
13942
14376
|
url: failure.url || "(unknown url)"
|
|
13943
14377
|
};
|
|
14378
|
+
if (failure.origin) http.origin = failure.origin;
|
|
13944
14379
|
if (failure.hostname) http.hostname = failure.hostname;
|
|
13945
14380
|
if (failure.pathname) http.pathname = failure.pathname;
|
|
13946
14381
|
if (failure.search) http.search = failure.search;
|
|
@@ -13953,14 +14388,69 @@
|
|
|
13953
14388
|
};
|
|
13954
14389
|
if (failure.errorName) fail.name = failure.errorName;
|
|
13955
14390
|
if (failure.errorMessage) fail.message = failure.errorMessage;
|
|
14391
|
+
const statusCode = typeof failure.status === "number" && failure.status > 0 ? failure.status : null;
|
|
13956
14392
|
return {
|
|
13957
14393
|
http,
|
|
13958
14394
|
failure: fail,
|
|
14395
|
+
network: {
|
|
14396
|
+
party: failure.party ?? "third_party",
|
|
14397
|
+
durationMs: failure.durationMs,
|
|
14398
|
+
aborted: failure.aborted ?? false,
|
|
14399
|
+
ok: failure.ok ?? false
|
|
14400
|
+
},
|
|
14401
|
+
// Top-level for server fingerprint compatibility (status only —
|
|
14402
|
+
// exception type lives on first-class `exception.values[0].type`).
|
|
14403
|
+
status_code: statusCode,
|
|
13959
14404
|
durationMs: failure.durationMs,
|
|
13960
14405
|
aborted: failure.aborted ?? false,
|
|
13961
14406
|
ok: failure.ok ?? false
|
|
13962
14407
|
};
|
|
13963
14408
|
}
|
|
14409
|
+
function networkExceptionData(failure, message) {
|
|
14410
|
+
return {
|
|
14411
|
+
values: [
|
|
14412
|
+
{
|
|
14413
|
+
type: networkExceptionClass(failure),
|
|
14414
|
+
value: message,
|
|
14415
|
+
mechanism: {
|
|
14416
|
+
type: "http",
|
|
14417
|
+
handled: true,
|
|
14418
|
+
synthetic: true
|
|
14419
|
+
}
|
|
14420
|
+
}
|
|
14421
|
+
]
|
|
14422
|
+
};
|
|
14423
|
+
}
|
|
14424
|
+
function scrubLegacyExceptionExtra(extra) {
|
|
14425
|
+
if (!extra) return void 0;
|
|
14426
|
+
const out = {};
|
|
14427
|
+
for (const [key, value] of Object.entries(extra)) {
|
|
14428
|
+
if (EXTRA_LOCATION_KEYS.has(key)) continue;
|
|
14429
|
+
out[key] = value;
|
|
14430
|
+
}
|
|
14431
|
+
return Object.keys(out).length ? out : void 0;
|
|
14432
|
+
}
|
|
14433
|
+
function buildExceptionFromError(err, context, inAppOptions) {
|
|
14434
|
+
const mechanism = context?.mechanism ?? {
|
|
14435
|
+
type: "generic",
|
|
14436
|
+
handled: true
|
|
14437
|
+
};
|
|
14438
|
+
const stacktrace = applySourceLocation(
|
|
14439
|
+
parseStackTrace(err.stack, inAppOptions),
|
|
14440
|
+
context?.source,
|
|
14441
|
+
inAppOptions
|
|
14442
|
+
);
|
|
14443
|
+
return {
|
|
14444
|
+
values: [
|
|
14445
|
+
{
|
|
14446
|
+
type: err.name || "Error",
|
|
14447
|
+
value: err.message || err.name || "Error",
|
|
14448
|
+
mechanism,
|
|
14449
|
+
...stacktrace ? { stacktrace } : {}
|
|
14450
|
+
}
|
|
14451
|
+
]
|
|
14452
|
+
};
|
|
14453
|
+
}
|
|
13964
14454
|
function mergeNetworkFailureContext(context, failure) {
|
|
13965
14455
|
return {
|
|
13966
14456
|
...context,
|
|
@@ -13997,13 +14487,17 @@
|
|
|
13997
14487
|
inlineStylesheet: options.inlineStylesheet ?? false,
|
|
13998
14488
|
blockSelector: options.blockSelector ?? "",
|
|
13999
14489
|
userId: options.userId,
|
|
14000
|
-
tags: options.tags,
|
|
14490
|
+
tags: mergeTags(options.tags),
|
|
14001
14491
|
disableDefaultIntegrations: options.disableDefaultIntegrations ?? false,
|
|
14002
14492
|
captureFailedRequests: options.captureFailedRequests ?? true,
|
|
14003
14493
|
captureNetworkErrors: options.captureNetworkErrors ?? true,
|
|
14494
|
+
networkErrorOrigins: options.networkErrorOrigins ?? [],
|
|
14004
14495
|
includeNetworkUrlQuery: options.captureRequestQueryParameters ?? options.includeNetworkUrlQuery ?? false,
|
|
14005
14496
|
failedRequestStatusCodes: options.failedRequestStatusCodes ?? [[500, 599]],
|
|
14006
|
-
failedRequestIgnoreUrls: options.failedRequestIgnoreUrls ?? []
|
|
14497
|
+
failedRequestIgnoreUrls: options.failedRequestIgnoreUrls ?? [],
|
|
14498
|
+
inAppAllowUrls: options.inAppAllowUrls ?? [],
|
|
14499
|
+
inAppDenyUrls: options.inAppDenyUrls ?? [],
|
|
14500
|
+
inAppOrigins: options.inAppOrigins ?? []
|
|
14007
14501
|
};
|
|
14008
14502
|
}
|
|
14009
14503
|
var RECENT_NETWORK_FAILURE_MS = 5e3;
|
|
@@ -14130,6 +14624,8 @@
|
|
|
14130
14624
|
installNetworkHook({
|
|
14131
14625
|
captureFailedRequests: this.options.captureFailedRequests,
|
|
14132
14626
|
captureNetworkErrors: this.options.captureNetworkErrors,
|
|
14627
|
+
networkErrorOrigins: this.options.networkErrorOrigins,
|
|
14628
|
+
pageOrigin: typeof location !== "undefined" ? location.origin : void 0,
|
|
14133
14629
|
includeNetworkUrlQuery: this.options.includeNetworkUrlQuery,
|
|
14134
14630
|
failedRequestStatusCodes: this.options.failedRequestStatusCodes,
|
|
14135
14631
|
failedRequestIgnoreUrls: this.options.failedRequestIgnoreUrls,
|
|
@@ -14148,17 +14644,21 @@
|
|
|
14148
14644
|
failureKind: "http",
|
|
14149
14645
|
aborted: false
|
|
14150
14646
|
};
|
|
14151
|
-
|
|
14152
|
-
|
|
14153
|
-
|
|
14154
|
-
|
|
14647
|
+
const message = `HTTP ${status}: ${method} ${url}`;
|
|
14648
|
+
void this.capture({
|
|
14649
|
+
message,
|
|
14650
|
+
level: status >= 500 ? "error" : "warning",
|
|
14651
|
+
title: networkExceptionClass(enriched),
|
|
14652
|
+
exception: networkExceptionData(enriched, message),
|
|
14653
|
+
platform: PLATFORM_JAVASCRIPT,
|
|
14654
|
+
context: {
|
|
14155
14655
|
tags: {
|
|
14156
14656
|
...networkFailureTags(enriched),
|
|
14157
14657
|
"http.status_code": String(status)
|
|
14158
14658
|
},
|
|
14159
14659
|
extra: networkFailureExtra(enriched)
|
|
14160
14660
|
}
|
|
14161
|
-
);
|
|
14661
|
+
});
|
|
14162
14662
|
},
|
|
14163
14663
|
onNetworkError: (meta) => {
|
|
14164
14664
|
this.rememberNetworkFailure(meta, { promoted: true });
|
|
@@ -14166,14 +14666,18 @@
|
|
|
14166
14666
|
const url = meta.url || "(unknown url)";
|
|
14167
14667
|
const errLabel = meta.errorName && meta.errorMessage ? `${meta.errorName}: ${meta.errorMessage}` : meta.errorMessage || meta.errorName || "Failed to fetch";
|
|
14168
14668
|
const prefix = meta.failureKind === "timeout" ? "Timeout error" : "Network error";
|
|
14169
|
-
|
|
14170
|
-
|
|
14171
|
-
|
|
14172
|
-
|
|
14669
|
+
const message = `${prefix}: ${method} ${url} \u2014 ${errLabel}`;
|
|
14670
|
+
void this.capture({
|
|
14671
|
+
message,
|
|
14672
|
+
level: "error",
|
|
14673
|
+
title: networkExceptionClass(meta),
|
|
14674
|
+
exception: networkExceptionData(meta, message),
|
|
14675
|
+
platform: PLATFORM_JAVASCRIPT,
|
|
14676
|
+
context: {
|
|
14173
14677
|
tags: networkFailureTags(meta),
|
|
14174
14678
|
extra: networkFailureExtra(meta)
|
|
14175
14679
|
}
|
|
14176
|
-
);
|
|
14680
|
+
});
|
|
14177
14681
|
}
|
|
14178
14682
|
}),
|
|
14179
14683
|
installVisibilityResumeHook(() => this.onForegroundResume())
|
|
@@ -14210,7 +14714,7 @@
|
|
|
14210
14714
|
if (this.capturing || this.ingestDisabled) return;
|
|
14211
14715
|
const err = error instanceof Error ? error : new Error(typeof error === "string" ? error : "Unknown error");
|
|
14212
14716
|
if (isAbortError(err)) return;
|
|
14213
|
-
const filename =
|
|
14717
|
+
const filename = context?.source?.filename;
|
|
14214
14718
|
if (isBrowserExtensionNoise({
|
|
14215
14719
|
message: err.message,
|
|
14216
14720
|
stack: err.stack,
|
|
@@ -14223,6 +14727,7 @@
|
|
|
14223
14727
|
}
|
|
14224
14728
|
const correlated = this.consumeCorrelatedNetworkFailure(err);
|
|
14225
14729
|
if (correlated?.promoted) return;
|
|
14730
|
+
if (correlated && correlated.party === "third_party") return;
|
|
14226
14731
|
const mergedContext = correlated ? mergeNetworkFailureContext(context, correlated) : context;
|
|
14227
14732
|
this.capturing = true;
|
|
14228
14733
|
try {
|
|
@@ -14231,6 +14736,12 @@
|
|
|
14231
14736
|
level: "error",
|
|
14232
14737
|
title: err.name || "Error",
|
|
14233
14738
|
stackTrace: err.stack,
|
|
14739
|
+
exception: buildExceptionFromError(
|
|
14740
|
+
err,
|
|
14741
|
+
mergedContext,
|
|
14742
|
+
this.inAppFrameOptions()
|
|
14743
|
+
),
|
|
14744
|
+
platform: PLATFORM_JAVASCRIPT,
|
|
14234
14745
|
context: mergedContext
|
|
14235
14746
|
});
|
|
14236
14747
|
} finally {
|
|
@@ -14246,6 +14757,13 @@
|
|
|
14246
14757
|
context
|
|
14247
14758
|
});
|
|
14248
14759
|
}
|
|
14760
|
+
/**
|
|
14761
|
+
* Returns a scoped capture facade that merges [tags] into every event.
|
|
14762
|
+
* Nested `withTags` calls merge further (later keys win).
|
|
14763
|
+
*/
|
|
14764
|
+
withTags(tags) {
|
|
14765
|
+
return createScopedTalaria(this, mergeTags(tags));
|
|
14766
|
+
}
|
|
14249
14767
|
async flush(opts) {
|
|
14250
14768
|
if (!this.options || !this.transport || this.closed) return;
|
|
14251
14769
|
const keepalive = opts?.keepalive ?? false;
|
|
@@ -14410,13 +14928,17 @@
|
|
|
14410
14928
|
}
|
|
14411
14929
|
const queuedMs = Math.max(0, Date.now() - occurredAt.getTime());
|
|
14412
14930
|
const tags = applyReplayCaptureTags(
|
|
14413
|
-
|
|
14414
|
-
|
|
14415
|
-
|
|
14416
|
-
|
|
14417
|
-
|
|
14931
|
+
mergeTags(
|
|
14932
|
+
this.browserContext ? browserContextTags(this.browserContext) : {},
|
|
14933
|
+
this.options.tags,
|
|
14934
|
+
args.context?.tags
|
|
14935
|
+
),
|
|
14418
14936
|
errorClipOutcome
|
|
14419
14937
|
);
|
|
14938
|
+
warnSuspiciousTags(tags, this.options.environment);
|
|
14939
|
+
const scrubbedContextExtra = scrubLegacyExceptionExtra(
|
|
14940
|
+
args.context?.extra
|
|
14941
|
+
);
|
|
14420
14942
|
const extra = mergeReplayCaptureExtra(
|
|
14421
14943
|
{
|
|
14422
14944
|
...this.browserContext ? {
|
|
@@ -14438,7 +14960,7 @@
|
|
|
14438
14960
|
// Time spent in capture() before ingest (mostly replay flush).
|
|
14439
14961
|
...queuedMs >= 50 ? { queuedMs } : {}
|
|
14440
14962
|
},
|
|
14441
|
-
...
|
|
14963
|
+
...scrubbedContextExtra ?? {}
|
|
14442
14964
|
},
|
|
14443
14965
|
errorClipOutcome
|
|
14444
14966
|
);
|
|
@@ -14450,6 +14972,8 @@
|
|
|
14450
14972
|
eventType: levelToEventType(args.level),
|
|
14451
14973
|
title: args.title ?? args.context?.title,
|
|
14452
14974
|
stackTrace: args.stackTrace,
|
|
14975
|
+
exception: args.exception,
|
|
14976
|
+
platform: args.platform,
|
|
14453
14977
|
release: this.options.release,
|
|
14454
14978
|
userId: args.context?.userId ?? this.options.userId,
|
|
14455
14979
|
sessionId: this.sessionId ?? void 0,
|
|
@@ -14699,12 +15223,36 @@
|
|
|
14699
15223
|
this.resetToBufferMode();
|
|
14700
15224
|
}
|
|
14701
15225
|
}
|
|
15226
|
+
inAppFrameOptions() {
|
|
15227
|
+
const opts = this.options;
|
|
15228
|
+
let pageOrigin;
|
|
15229
|
+
try {
|
|
15230
|
+
pageOrigin = resolvePageOrigin(
|
|
15231
|
+
typeof window !== "undefined" ? window.location?.origin : void 0
|
|
15232
|
+
);
|
|
15233
|
+
} catch {
|
|
15234
|
+
pageOrigin = void 0;
|
|
15235
|
+
}
|
|
15236
|
+
return {
|
|
15237
|
+
pageOrigin,
|
|
15238
|
+
allowUrls: opts?.inAppAllowUrls,
|
|
15239
|
+
denyUrls: opts?.inAppDenyUrls,
|
|
15240
|
+
inAppOrigins: opts?.inAppOrigins
|
|
15241
|
+
};
|
|
15242
|
+
}
|
|
14702
15243
|
pruneRecentNetworkFailures(now = Date.now()) {
|
|
14703
15244
|
this.recentNetworkFailures = this.recentNetworkFailures.filter(
|
|
14704
15245
|
(f) => now - f.at <= RECENT_NETWORK_FAILURE_MS
|
|
14705
15246
|
);
|
|
14706
15247
|
}
|
|
14707
15248
|
rememberNetworkFailure(meta, opts) {
|
|
15249
|
+
if (this.options) {
|
|
15250
|
+
const ignore = buildFailedRequestIgnoreUrls(
|
|
15251
|
+
this.options.failedRequestIgnoreUrls,
|
|
15252
|
+
this.options.baseUrl
|
|
15253
|
+
);
|
|
15254
|
+
if (urlMatchesIgnoreList(meta.url || "", ignore)) return;
|
|
15255
|
+
}
|
|
14708
15256
|
const now = Date.now();
|
|
14709
15257
|
this.pruneRecentNetworkFailures(now);
|
|
14710
15258
|
for (let i = this.recentNetworkFailures.length - 1; i >= 0; i--) {
|
|
@@ -14715,6 +15263,8 @@
|
|
|
14715
15263
|
existing.errorName = meta.errorName ?? existing.errorName;
|
|
14716
15264
|
existing.aborted = meta.aborted ?? existing.aborted;
|
|
14717
15265
|
existing.failureKind = meta.failureKind ?? existing.failureKind;
|
|
15266
|
+
existing.party = meta.party ?? existing.party;
|
|
15267
|
+
existing.origin = meta.origin ?? existing.origin;
|
|
14718
15268
|
return;
|
|
14719
15269
|
}
|
|
14720
15270
|
}
|
|
@@ -14725,11 +15275,12 @@
|
|
|
14725
15275
|
});
|
|
14726
15276
|
}
|
|
14727
15277
|
/**
|
|
14728
|
-
* Find a recent transport failure for a bare fetch TypeError.
|
|
15278
|
+
* Find a recent transport failure for a bare fetch TypeError / TimeoutError.
|
|
14729
15279
|
* Consumes the entry so a later duplicate path cannot reuse it.
|
|
14730
15280
|
*/
|
|
14731
15281
|
consumeCorrelatedNetworkFailure(error) {
|
|
14732
|
-
if (!
|
|
15282
|
+
if (!isCorrelatableTransportError(error)) return null;
|
|
15283
|
+
const wantKind = isTimeoutError(error) ? "timeout" : "network";
|
|
14733
15284
|
const now = Date.now();
|
|
14734
15285
|
this.pruneRecentNetworkFailures(now);
|
|
14735
15286
|
const takeAt = (index2) => {
|
|
@@ -14738,14 +15289,14 @@
|
|
|
14738
15289
|
};
|
|
14739
15290
|
for (let i = this.recentNetworkFailures.length - 1; i >= 0; i--) {
|
|
14740
15291
|
const failure = this.recentNetworkFailures[i];
|
|
14741
|
-
if (failure.aborted || failure.failureKind !==
|
|
15292
|
+
if (failure.aborted || failure.failureKind !== wantKind) continue;
|
|
14742
15293
|
if (failure.errorMessage && failure.errorMessage === error.message) {
|
|
14743
15294
|
return takeAt(i);
|
|
14744
15295
|
}
|
|
14745
15296
|
}
|
|
14746
15297
|
for (let i = this.recentNetworkFailures.length - 1; i >= 0; i--) {
|
|
14747
15298
|
const failure = this.recentNetworkFailures[i];
|
|
14748
|
-
if (failure.aborted || failure.failureKind !==
|
|
15299
|
+
if (failure.aborted || failure.failureKind !== wantKind) continue;
|
|
14749
15300
|
return takeAt(i);
|
|
14750
15301
|
}
|
|
14751
15302
|
return null;
|
|
@@ -14763,7 +15314,8 @@
|
|
|
14763
15314
|
return;
|
|
14764
15315
|
}
|
|
14765
15316
|
void this.captureException(error, {
|
|
14766
|
-
|
|
15317
|
+
mechanism: { type: "onerror", handled: false },
|
|
15318
|
+
source: {
|
|
14767
15319
|
filename: event.filename,
|
|
14768
15320
|
lineno: event.lineno,
|
|
14769
15321
|
colno: event.colno
|
|
@@ -14785,7 +15337,9 @@
|
|
|
14785
15337
|
})) {
|
|
14786
15338
|
return;
|
|
14787
15339
|
}
|
|
14788
|
-
void this.captureException(reason
|
|
15340
|
+
void this.captureException(reason, {
|
|
15341
|
+
mechanism: { type: "unhandledrejection", handled: false }
|
|
15342
|
+
});
|
|
14789
15343
|
};
|
|
14790
15344
|
window.addEventListener("error", onError);
|
|
14791
15345
|
window.addEventListener("unhandledrejection", onRejection);
|
|
@@ -15047,6 +15601,23 @@
|
|
|
15047
15601
|
}
|
|
15048
15602
|
}
|
|
15049
15603
|
};
|
|
15604
|
+
function createScopedTalaria(client2, scopeTags) {
|
|
15605
|
+
const mergeContext = (context) => ({
|
|
15606
|
+
...context,
|
|
15607
|
+
tags: mergeTags(scopeTags, context?.tags)
|
|
15608
|
+
});
|
|
15609
|
+
return {
|
|
15610
|
+
captureException(error, context) {
|
|
15611
|
+
return client2.captureException(error, mergeContext(context));
|
|
15612
|
+
},
|
|
15613
|
+
captureMessage(message, level, context) {
|
|
15614
|
+
return client2.captureMessage(message, level, mergeContext(context));
|
|
15615
|
+
},
|
|
15616
|
+
withTags(tags) {
|
|
15617
|
+
return createScopedTalaria(client2, mergeTags(scopeTags, tags));
|
|
15618
|
+
}
|
|
15619
|
+
};
|
|
15620
|
+
}
|
|
15050
15621
|
|
|
15051
15622
|
// src/index.ts
|
|
15052
15623
|
var client = new TalariaClient();
|
|
@@ -15060,6 +15631,9 @@
|
|
|
15060
15631
|
captureMessage(message, level, context) {
|
|
15061
15632
|
return client.captureMessage(message, level, context);
|
|
15062
15633
|
},
|
|
15634
|
+
withTags(tags) {
|
|
15635
|
+
return client.withTags(tags);
|
|
15636
|
+
},
|
|
15063
15637
|
getReplayId() {
|
|
15064
15638
|
return client.getReplayId();
|
|
15065
15639
|
},
|