@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
package/dist/index.js
CHANGED
|
@@ -270,9 +270,262 @@ async function collectBrowserContext() {
|
|
|
270
270
|
return base;
|
|
271
271
|
}
|
|
272
272
|
|
|
273
|
+
// src/utils/tags.ts
|
|
274
|
+
var MAX_TAGS_PER_EVENT = 20;
|
|
275
|
+
var MAX_TAG_KEY_LENGTH = 64;
|
|
276
|
+
var MAX_TAG_VALUE_LENGTH = 128;
|
|
277
|
+
var MAX_TAG_TOTAL_UTF8_BYTES = 2048;
|
|
278
|
+
var KEY_PATTERN = /^[a-z0-9_.-]+$/;
|
|
279
|
+
var HIGH_CARDINALITY_TAG_KEYS = /* @__PURE__ */ new Set([
|
|
280
|
+
"user_id",
|
|
281
|
+
"userid",
|
|
282
|
+
"request_id",
|
|
283
|
+
"requestid",
|
|
284
|
+
"business_id",
|
|
285
|
+
"order_id",
|
|
286
|
+
"email",
|
|
287
|
+
"url",
|
|
288
|
+
"uuid",
|
|
289
|
+
"session_id",
|
|
290
|
+
"trace_id",
|
|
291
|
+
"span_id"
|
|
292
|
+
]);
|
|
293
|
+
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;
|
|
294
|
+
var EMAIL_RE = /^[^@\s]+@[^@\s]+\.[^@\s]+$/;
|
|
295
|
+
var LONG_NUMERIC_RE = /^\d{8,}$/;
|
|
296
|
+
function utf8Bytes(s) {
|
|
297
|
+
if (typeof TextEncoder !== "undefined") {
|
|
298
|
+
return new TextEncoder().encode(s).length;
|
|
299
|
+
}
|
|
300
|
+
return unescape(encodeURIComponent(s)).length;
|
|
301
|
+
}
|
|
302
|
+
function normalizeKey(raw) {
|
|
303
|
+
const key = raw.trim().toLowerCase();
|
|
304
|
+
if (!key || key.length > MAX_TAG_KEY_LENGTH) return null;
|
|
305
|
+
if (!KEY_PATTERN.test(key)) return null;
|
|
306
|
+
return key;
|
|
307
|
+
}
|
|
308
|
+
function normalizeValue(raw) {
|
|
309
|
+
if (raw == null) return null;
|
|
310
|
+
const value = String(raw).trim();
|
|
311
|
+
if (!value) return null;
|
|
312
|
+
return value.length <= MAX_TAG_VALUE_LENGTH ? value : value.slice(0, MAX_TAG_VALUE_LENGTH);
|
|
313
|
+
}
|
|
314
|
+
function normalizeTags(tags) {
|
|
315
|
+
if (!tags) return {};
|
|
316
|
+
const result2 = {};
|
|
317
|
+
let totalBytes = 0;
|
|
318
|
+
for (const [rawKey, rawValue] of Object.entries(tags)) {
|
|
319
|
+
if (Object.keys(result2).length >= MAX_TAGS_PER_EVENT) break;
|
|
320
|
+
const key = normalizeKey(rawKey);
|
|
321
|
+
if (!key) continue;
|
|
322
|
+
const value = normalizeValue(rawValue);
|
|
323
|
+
if (value == null) continue;
|
|
324
|
+
if (result2[key] != null) {
|
|
325
|
+
totalBytes -= utf8Bytes(key) + utf8Bytes(result2[key]);
|
|
326
|
+
}
|
|
327
|
+
const entryBytes = utf8Bytes(key) + utf8Bytes(value);
|
|
328
|
+
if (totalBytes + entryBytes > MAX_TAG_TOTAL_UTF8_BYTES) continue;
|
|
329
|
+
result2[key] = value;
|
|
330
|
+
totalBytes += entryBytes;
|
|
331
|
+
}
|
|
332
|
+
return result2;
|
|
333
|
+
}
|
|
334
|
+
function mergeTags(...parts) {
|
|
335
|
+
const merged = {};
|
|
336
|
+
for (const part of parts) {
|
|
337
|
+
if (!part) continue;
|
|
338
|
+
Object.assign(merged, part);
|
|
339
|
+
}
|
|
340
|
+
return normalizeTags(merged);
|
|
341
|
+
}
|
|
342
|
+
function looksHighCardinalityValue(value) {
|
|
343
|
+
return UUID_RE.test(value) || EMAIL_RE.test(value) || LONG_NUMERIC_RE.test(value);
|
|
344
|
+
}
|
|
345
|
+
function warnSuspiciousTags(tags, environment) {
|
|
346
|
+
if (!environment || environment === "production") return;
|
|
347
|
+
if (typeof console === "undefined" || typeof console.warn !== "function") {
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
350
|
+
for (const [key, value] of Object.entries(tags)) {
|
|
351
|
+
if (HIGH_CARDINALITY_TAG_KEYS.has(key)) {
|
|
352
|
+
console.warn(
|
|
353
|
+
`@newtalaria/browser: Tag "${key}" appears to have high cardinality. Consider moving it to context/extra.`
|
|
354
|
+
);
|
|
355
|
+
continue;
|
|
356
|
+
}
|
|
357
|
+
if (looksHighCardinalityValue(value)) {
|
|
358
|
+
console.warn(
|
|
359
|
+
`@newtalaria/browser: Tag "${key}" value looks high-cardinality. Consider moving it to context/extra.`
|
|
360
|
+
);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
var RESERVED_TAG_KEYS = [
|
|
365
|
+
"service",
|
|
366
|
+
"platform",
|
|
367
|
+
"feature",
|
|
368
|
+
"operation",
|
|
369
|
+
"component",
|
|
370
|
+
"runtime",
|
|
371
|
+
"runtime_version"
|
|
372
|
+
];
|
|
373
|
+
|
|
374
|
+
// src/utils/stacktrace.ts
|
|
375
|
+
var V8_FRAME = /^\s*at\s+(?:(.+?)\s+\()?(.+?):(\d+):(\d+)\)?\s*$/;
|
|
376
|
+
var V8_FRAME_BARE = /^\s*at\s+(.+)\s*$/;
|
|
377
|
+
var EXTENSION_URL2 = /(?:chrome|moz|safari|safari-web|ms-browser)-extension:\/\//i;
|
|
378
|
+
function parseStackTrace(stack, inAppOptions) {
|
|
379
|
+
if (!stack || !stack.trim()) return void 0;
|
|
380
|
+
const parsed = [];
|
|
381
|
+
for (const line of stack.split("\n")) {
|
|
382
|
+
const frame = parseStackLine(line, inAppOptions);
|
|
383
|
+
if (frame) parsed.push(frame);
|
|
384
|
+
}
|
|
385
|
+
if (parsed.length === 0) return void 0;
|
|
386
|
+
parsed.reverse();
|
|
387
|
+
return { frames: parsed };
|
|
388
|
+
}
|
|
389
|
+
function parseStackLine(line, inAppOptions) {
|
|
390
|
+
if (!/^\s*at\s+/.test(line)) return null;
|
|
391
|
+
const v8 = V8_FRAME.exec(line);
|
|
392
|
+
if (v8) {
|
|
393
|
+
const functionName = cleanFunction(v8[1]);
|
|
394
|
+
const absPath = stripQuery(v8[2] ?? "");
|
|
395
|
+
const lineno = Number.parseInt(v8[3] ?? "", 10);
|
|
396
|
+
const colno = Number.parseInt(v8[4] ?? "", 10);
|
|
397
|
+
return {
|
|
398
|
+
functionName,
|
|
399
|
+
absPath: absPath || void 0,
|
|
400
|
+
filename: basename(absPath),
|
|
401
|
+
lineno: Number.isFinite(lineno) ? lineno : void 0,
|
|
402
|
+
colno: Number.isFinite(colno) ? colno : void 0,
|
|
403
|
+
inApp: isInAppFrame(absPath, inAppOptions),
|
|
404
|
+
platform: "javascript"
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
const bare = V8_FRAME_BARE.exec(line);
|
|
408
|
+
if (bare) {
|
|
409
|
+
const functionName = cleanFunction(bare[1]);
|
|
410
|
+
if (!functionName) return null;
|
|
411
|
+
return {
|
|
412
|
+
functionName,
|
|
413
|
+
inApp: false,
|
|
414
|
+
platform: "javascript"
|
|
415
|
+
};
|
|
416
|
+
}
|
|
417
|
+
return null;
|
|
418
|
+
}
|
|
419
|
+
function applySourceLocation(stacktrace, source, inAppOptions) {
|
|
420
|
+
if (!source) return stacktrace;
|
|
421
|
+
const filename = source.filename?.trim() || void 0;
|
|
422
|
+
const lineno = typeof source.lineno === "number" && source.lineno > 0 ? source.lineno : void 0;
|
|
423
|
+
const colno = typeof source.colno === "number" && source.colno >= 0 ? source.colno : void 0;
|
|
424
|
+
if (!filename && lineno == null && colno == null) return stacktrace;
|
|
425
|
+
if (!stacktrace || stacktrace.frames.length === 0) {
|
|
426
|
+
if (!filename && lineno == null) return stacktrace;
|
|
427
|
+
const absPath = filename;
|
|
428
|
+
return {
|
|
429
|
+
frames: [
|
|
430
|
+
{
|
|
431
|
+
filename: absPath ? basename(absPath) : void 0,
|
|
432
|
+
absPath,
|
|
433
|
+
lineno,
|
|
434
|
+
colno,
|
|
435
|
+
inApp: absPath ? isInAppFrame(absPath, inAppOptions) : true,
|
|
436
|
+
platform: "javascript"
|
|
437
|
+
}
|
|
438
|
+
]
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
const frames = stacktrace.frames.slice();
|
|
442
|
+
const top = { ...frames[frames.length - 1] };
|
|
443
|
+
if (filename) {
|
|
444
|
+
top.absPath = filename;
|
|
445
|
+
top.filename = basename(filename);
|
|
446
|
+
top.inApp = isInAppFrame(filename, inAppOptions);
|
|
447
|
+
}
|
|
448
|
+
if (lineno != null) top.lineno = lineno;
|
|
449
|
+
if (colno != null) top.colno = colno;
|
|
450
|
+
frames[frames.length - 1] = top;
|
|
451
|
+
return { ...stacktrace, frames };
|
|
452
|
+
}
|
|
453
|
+
function isInAppFrame(path, options) {
|
|
454
|
+
const lower = path.toLowerCase();
|
|
455
|
+
if (!lower) return true;
|
|
456
|
+
if (lower.includes("node_modules")) return false;
|
|
457
|
+
if (EXTENSION_URL2.test(path) || lower.includes("webkit-masked-url://")) {
|
|
458
|
+
return false;
|
|
459
|
+
}
|
|
460
|
+
if (lower.includes("@newtalaria/browser")) return false;
|
|
461
|
+
if (matchesUrlList(path, options?.denyUrls)) return false;
|
|
462
|
+
if (matchesUrlList(path, options?.allowUrls)) return true;
|
|
463
|
+
const frameOrigin = tryParseOrigin(path);
|
|
464
|
+
if (frameOrigin != null) {
|
|
465
|
+
const pageOrigin = normalizeOrigin(options?.pageOrigin);
|
|
466
|
+
if (pageOrigin && frameOrigin === pageOrigin) return true;
|
|
467
|
+
const extra = options?.inAppOrigins ?? [];
|
|
468
|
+
for (const origin of extra) {
|
|
469
|
+
if (normalizeOrigin(origin) === frameOrigin) return true;
|
|
470
|
+
}
|
|
471
|
+
return false;
|
|
472
|
+
}
|
|
473
|
+
return true;
|
|
474
|
+
}
|
|
475
|
+
function matchesUrlList(path, patterns) {
|
|
476
|
+
if (!patterns || patterns.length === 0) return false;
|
|
477
|
+
for (const pattern of patterns) {
|
|
478
|
+
if (typeof pattern === "string") {
|
|
479
|
+
if (pattern && path.includes(pattern)) return true;
|
|
480
|
+
} else if (pattern.test(path)) {
|
|
481
|
+
return true;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
return false;
|
|
485
|
+
}
|
|
486
|
+
function tryParseOrigin(path) {
|
|
487
|
+
if (!/^https?:\/\//i.test(path)) return null;
|
|
488
|
+
try {
|
|
489
|
+
return new URL(path).origin;
|
|
490
|
+
} catch {
|
|
491
|
+
return null;
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
function normalizeOrigin(origin) {
|
|
495
|
+
if (!origin || !origin.trim()) return null;
|
|
496
|
+
const trimmed = origin.trim();
|
|
497
|
+
try {
|
|
498
|
+
if (/^https?:\/\//i.test(trimmed)) {
|
|
499
|
+
return new URL(trimmed).origin;
|
|
500
|
+
}
|
|
501
|
+
return trimmed;
|
|
502
|
+
} catch {
|
|
503
|
+
return trimmed;
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
function resolvePageOrigin(originOrUrl) {
|
|
507
|
+
return normalizeOrigin(originOrUrl) ?? void 0;
|
|
508
|
+
}
|
|
509
|
+
function cleanFunction(raw) {
|
|
510
|
+
if (raw == null) return void 0;
|
|
511
|
+
const value = raw.trim();
|
|
512
|
+
return value.length === 0 ? void 0 : value;
|
|
513
|
+
}
|
|
514
|
+
function stripQuery(path) {
|
|
515
|
+
const q = path.indexOf("?");
|
|
516
|
+
return q >= 0 ? path.slice(0, q) : path;
|
|
517
|
+
}
|
|
518
|
+
function basename(path) {
|
|
519
|
+
if (!path) return void 0;
|
|
520
|
+
const normalized = stripQuery(path);
|
|
521
|
+
const parts = normalized.split(/[/\\]/);
|
|
522
|
+
const last = parts[parts.length - 1];
|
|
523
|
+
return last || normalized;
|
|
524
|
+
}
|
|
525
|
+
|
|
273
526
|
// src/sdk_meta.ts
|
|
274
527
|
var SDK_NAME = "@newtalaria/browser";
|
|
275
|
-
var SDK_VERSION = "0.1.
|
|
528
|
+
var SDK_VERSION = "0.1.18";
|
|
276
529
|
|
|
277
530
|
// src/transport/serverpod.ts
|
|
278
531
|
var ServerpodTransport = class {
|
|
@@ -330,6 +583,9 @@ async function ingestEvent(transport, params) {
|
|
|
330
583
|
if (params.eventType) input2.eventType = params.eventType;
|
|
331
584
|
if (params.title) input2.title = params.title;
|
|
332
585
|
if (params.stackTrace) input2.stackTrace = params.stackTrace;
|
|
586
|
+
if (params.exception) input2.exception = serializeException(params.exception);
|
|
587
|
+
if (params.debugMeta) input2.debugMeta = serializeDebugMeta(params.debugMeta);
|
|
588
|
+
if (params.platform) input2.platform = params.platform;
|
|
333
589
|
if (params.release) input2.release = params.release;
|
|
334
590
|
if (params.userId) input2.userId = params.userId;
|
|
335
591
|
if (params.sessionId) input2.sessionId = params.sessionId;
|
|
@@ -346,6 +602,89 @@ async function ingestEvent(transport, params) {
|
|
|
346
602
|
{ keepalive: params.keepalive }
|
|
347
603
|
);
|
|
348
604
|
}
|
|
605
|
+
function serializeException(data) {
|
|
606
|
+
return {
|
|
607
|
+
__className__: "ExceptionDataDto",
|
|
608
|
+
values: data.values.map(serializeExceptionValue)
|
|
609
|
+
};
|
|
610
|
+
}
|
|
611
|
+
function serializeExceptionValue(value) {
|
|
612
|
+
const out = {
|
|
613
|
+
__className__: "ExceptionValueDto"
|
|
614
|
+
};
|
|
615
|
+
if (value.type != null) out.type = value.type;
|
|
616
|
+
if (value.value != null) out.value = value.value;
|
|
617
|
+
if (value.module != null) out.module = value.module;
|
|
618
|
+
if (value.threadId != null) out.threadId = value.threadId;
|
|
619
|
+
if (value.code != null) out.code = value.code;
|
|
620
|
+
if (value.mechanism) out.mechanism = serializeMechanism(value.mechanism);
|
|
621
|
+
if (value.stacktrace) out.stacktrace = serializeStackTrace(value.stacktrace);
|
|
622
|
+
return out;
|
|
623
|
+
}
|
|
624
|
+
function serializeMechanism(mechanism) {
|
|
625
|
+
const out = {
|
|
626
|
+
__className__: "ExceptionMechanismDto",
|
|
627
|
+
type: mechanism.type
|
|
628
|
+
};
|
|
629
|
+
if (mechanism.handled != null) out.handled = mechanism.handled;
|
|
630
|
+
if (mechanism.synthetic != null) out.synthetic = mechanism.synthetic;
|
|
631
|
+
return out;
|
|
632
|
+
}
|
|
633
|
+
function serializeStackTrace(stack) {
|
|
634
|
+
const out = {
|
|
635
|
+
__className__: "StackTraceDto",
|
|
636
|
+
frames: stack.frames.map(serializeStackFrame)
|
|
637
|
+
};
|
|
638
|
+
if (stack.registers) out.registers = stack.registers;
|
|
639
|
+
return out;
|
|
640
|
+
}
|
|
641
|
+
function serializeStackFrame(frame) {
|
|
642
|
+
const out = {
|
|
643
|
+
__className__: "StackFrameDto"
|
|
644
|
+
};
|
|
645
|
+
if (frame.filename != null) out.filename = frame.filename;
|
|
646
|
+
if (frame.absPath != null) out.absPath = frame.absPath;
|
|
647
|
+
if (frame.functionName != null) out.functionName = frame.functionName;
|
|
648
|
+
if (frame.rawFunction != null) out.rawFunction = frame.rawFunction;
|
|
649
|
+
if (frame.module != null) out.module = frame.module;
|
|
650
|
+
if (frame.package != null) out.package = frame.package;
|
|
651
|
+
if (frame.platform != null) out.platform = frame.platform;
|
|
652
|
+
if (frame.lineno != null) out.lineno = frame.lineno;
|
|
653
|
+
if (frame.colno != null) out.colno = frame.colno;
|
|
654
|
+
if (frame.inApp != null) out.inApp = frame.inApp;
|
|
655
|
+
if (frame.instructionAddr != null) out.instructionAddr = frame.instructionAddr;
|
|
656
|
+
if (frame.symbolAddr != null) out.symbolAddr = frame.symbolAddr;
|
|
657
|
+
if (frame.imageAddr != null) out.imageAddr = frame.imageAddr;
|
|
658
|
+
if (frame.addrMode != null) out.addrMode = frame.addrMode;
|
|
659
|
+
if (frame.contextLine != null) out.contextLine = frame.contextLine;
|
|
660
|
+
if (frame.preContext != null) out.preContext = frame.preContext;
|
|
661
|
+
if (frame.postContext != null) out.postContext = frame.postContext;
|
|
662
|
+
if (frame.vars != null) out.vars = frame.vars;
|
|
663
|
+
if (frame.stackStart != null) out.stackStart = frame.stackStart;
|
|
664
|
+
return out;
|
|
665
|
+
}
|
|
666
|
+
function serializeDebugMeta(meta) {
|
|
667
|
+
const out = {
|
|
668
|
+
__className__: "DebugMetaDto"
|
|
669
|
+
};
|
|
670
|
+
if (meta.images) {
|
|
671
|
+
out.images = meta.images.map((image) => {
|
|
672
|
+
const img = {
|
|
673
|
+
__className__: "DebugImageDto"
|
|
674
|
+
};
|
|
675
|
+
if (image.type != null) img.type = image.type;
|
|
676
|
+
if (image.imageAddr != null) img.imageAddr = image.imageAddr;
|
|
677
|
+
if (image.imageSize != null) img.imageSize = image.imageSize;
|
|
678
|
+
if (image.debugId != null) img.debugId = image.debugId;
|
|
679
|
+
if (image.debugFile != null) img.debugFile = image.debugFile;
|
|
680
|
+
if (image.codeId != null) img.codeId = image.codeId;
|
|
681
|
+
if (image.codeFile != null) img.codeFile = image.codeFile;
|
|
682
|
+
if (image.arch != null) img.arch = image.arch;
|
|
683
|
+
return img;
|
|
684
|
+
});
|
|
685
|
+
}
|
|
686
|
+
return out;
|
|
687
|
+
}
|
|
349
688
|
|
|
350
689
|
// src/utils/gzip.ts
|
|
351
690
|
async function gzipBytes(data) {
|
|
@@ -13482,18 +13821,22 @@ var { freezePage } = record;
|
|
|
13482
13821
|
var { takeFullSnapshot } = record;
|
|
13483
13822
|
|
|
13484
13823
|
// src/replay/privacy.ts
|
|
13485
|
-
var
|
|
13824
|
+
var SENSITIVE_QUERY_KEY = /^(?:token|secret|password|auth|api[_-]?key|access[_-]?token|gclid|fbclid|gcl_au|msclkid|_ga(?:_.*)?|cid|sid)$/i;
|
|
13825
|
+
var SENSITIVE_QUERY_LEGACY = /(?:^|[?&])(token|secret|password|auth|api[_-]?key|access[_-]?token|gclid|fbclid|gcl_au|msclkid|_ga(?:_[^=&#]*)?|cid|sid)=([^&#]*)/gi;
|
|
13826
|
+
function isSensitiveQueryKey(key) {
|
|
13827
|
+
return SENSITIVE_QUERY_KEY.test(key);
|
|
13828
|
+
}
|
|
13486
13829
|
function redactUrl(raw) {
|
|
13487
13830
|
try {
|
|
13488
13831
|
const url = new URL(raw, typeof location !== "undefined" ? location.href : void 0);
|
|
13489
13832
|
for (const key of [...url.searchParams.keys()]) {
|
|
13490
|
-
if (
|
|
13833
|
+
if (isSensitiveQueryKey(key)) {
|
|
13491
13834
|
url.searchParams.set(key, "[Filtered]");
|
|
13492
13835
|
}
|
|
13493
13836
|
}
|
|
13494
13837
|
return url.toString();
|
|
13495
13838
|
} catch {
|
|
13496
|
-
return raw.replace(
|
|
13839
|
+
return raw.replace(SENSITIVE_QUERY_LEGACY, (_m, name) => `${name}=[Filtered]`);
|
|
13497
13840
|
}
|
|
13498
13841
|
}
|
|
13499
13842
|
function sanitizeNetworkUrl(raw, opts) {
|
|
@@ -13590,6 +13933,9 @@ function startRecorder(options) {
|
|
|
13590
13933
|
function isAbortError(error) {
|
|
13591
13934
|
return error instanceof Error && error.name === "AbortError";
|
|
13592
13935
|
}
|
|
13936
|
+
function isTimeoutError(error) {
|
|
13937
|
+
return error instanceof Error && error.name === "TimeoutError";
|
|
13938
|
+
}
|
|
13593
13939
|
function isLikelyNetworkFetchError(error) {
|
|
13594
13940
|
if (!(error instanceof Error)) return false;
|
|
13595
13941
|
if (error.name === "AbortError" || error.name === "TimeoutError") return false;
|
|
@@ -13597,6 +13943,9 @@ function isLikelyNetworkFetchError(error) {
|
|
|
13597
13943
|
const msg = error.message.toLowerCase().trim();
|
|
13598
13944
|
return msg === "failed to fetch" || msg === "load failed" || msg === "networkerror when attempting to fetch resource." || msg.startsWith("networkerror") || msg.includes("failed to fetch");
|
|
13599
13945
|
}
|
|
13946
|
+
function isCorrelatableTransportError(error) {
|
|
13947
|
+
return isLikelyNetworkFetchError(error) || isTimeoutError(error);
|
|
13948
|
+
}
|
|
13600
13949
|
function describeUnknownError(error) {
|
|
13601
13950
|
if (error instanceof Error) {
|
|
13602
13951
|
return {
|
|
@@ -13744,6 +14093,56 @@ function urlMatchesIgnoreList(url, ignoreUrls) {
|
|
|
13744
14093
|
}
|
|
13745
14094
|
return false;
|
|
13746
14095
|
}
|
|
14096
|
+
function normalizeNetworkOrigin(raw) {
|
|
14097
|
+
const trimmed = (raw || "").trim();
|
|
14098
|
+
if (!trimmed || trimmed === "*") return trimmed;
|
|
14099
|
+
try {
|
|
14100
|
+
return new URL(trimmed).origin;
|
|
14101
|
+
} catch {
|
|
14102
|
+
try {
|
|
14103
|
+
return new URL(`https://${trimmed}`).origin;
|
|
14104
|
+
} catch {
|
|
14105
|
+
return trimmed.replace(/\/+$/, "");
|
|
14106
|
+
}
|
|
14107
|
+
}
|
|
14108
|
+
}
|
|
14109
|
+
function resolvePageOrigin2(pageOrigin) {
|
|
14110
|
+
if (pageOrigin) {
|
|
14111
|
+
try {
|
|
14112
|
+
return new URL(pageOrigin).origin;
|
|
14113
|
+
} catch {
|
|
14114
|
+
return pageOrigin.replace(/\/+$/, "");
|
|
14115
|
+
}
|
|
14116
|
+
}
|
|
14117
|
+
if (typeof location !== "undefined" && location.origin) {
|
|
14118
|
+
return location.origin;
|
|
14119
|
+
}
|
|
14120
|
+
return "";
|
|
14121
|
+
}
|
|
14122
|
+
function resolveRequestOrigin(rawUrl, pageOrigin) {
|
|
14123
|
+
const base = pageOrigin || (typeof location !== "undefined" ? location.href : void 0);
|
|
14124
|
+
try {
|
|
14125
|
+
return new URL(rawUrl, base).origin;
|
|
14126
|
+
} catch {
|
|
14127
|
+
return "";
|
|
14128
|
+
}
|
|
14129
|
+
}
|
|
14130
|
+
function isAllowedNetworkOrigin(requestOrigin, opts) {
|
|
14131
|
+
if (!requestOrigin) return false;
|
|
14132
|
+
const allow = opts.networkErrorOrigins.map(normalizeNetworkOrigin);
|
|
14133
|
+
if (allow.includes("*")) return true;
|
|
14134
|
+
const page = resolvePageOrigin2(opts.pageOrigin);
|
|
14135
|
+
if (page && requestOrigin === page) return true;
|
|
14136
|
+
return allow.includes(requestOrigin);
|
|
14137
|
+
}
|
|
14138
|
+
function classifyNetworkParty(requestOrigin, pageOrigin) {
|
|
14139
|
+
const page = resolvePageOrigin2(pageOrigin);
|
|
14140
|
+
if (page && requestOrigin && requestOrigin === page) return "first_party";
|
|
14141
|
+
return "third_party";
|
|
14142
|
+
}
|
|
14143
|
+
function isHttpOkStatus(status) {
|
|
14144
|
+
return status >= 200 && status < 300;
|
|
14145
|
+
}
|
|
13747
14146
|
function shouldPromoteFailedRequest(meta, opts) {
|
|
13748
14147
|
if (!opts.captureFailedRequests) return false;
|
|
13749
14148
|
if (typeof meta.status !== "number" || Number.isNaN(meta.status)) return false;
|
|
@@ -13754,6 +14153,13 @@ function shouldPromoteFailedRequest(meta, opts) {
|
|
|
13754
14153
|
opts.talariaBaseUrl
|
|
13755
14154
|
);
|
|
13756
14155
|
if (urlMatchesIgnoreList(meta.url || "", ignore)) return false;
|
|
14156
|
+
const requestOrigin = meta.origin || resolveRequestOrigin(meta.url || "", opts.pageOrigin);
|
|
14157
|
+
if (!isAllowedNetworkOrigin(requestOrigin, {
|
|
14158
|
+
networkErrorOrigins: opts.networkErrorOrigins ?? [],
|
|
14159
|
+
pageOrigin: opts.pageOrigin
|
|
14160
|
+
})) {
|
|
14161
|
+
return false;
|
|
14162
|
+
}
|
|
13757
14163
|
return true;
|
|
13758
14164
|
}
|
|
13759
14165
|
function shouldPromoteNetworkError(meta, opts) {
|
|
@@ -13767,6 +14173,13 @@ function shouldPromoteNetworkError(meta, opts) {
|
|
|
13767
14173
|
opts.talariaBaseUrl
|
|
13768
14174
|
);
|
|
13769
14175
|
if (urlMatchesIgnoreList(meta.url || "", ignore)) return false;
|
|
14176
|
+
const requestOrigin = meta.origin || resolveRequestOrigin(meta.url || "", opts.pageOrigin);
|
|
14177
|
+
if (!isAllowedNetworkOrigin(requestOrigin, {
|
|
14178
|
+
networkErrorOrigins: opts.networkErrorOrigins ?? [],
|
|
14179
|
+
pageOrigin: opts.pageOrigin
|
|
14180
|
+
})) {
|
|
14181
|
+
return false;
|
|
14182
|
+
}
|
|
13770
14183
|
return true;
|
|
13771
14184
|
}
|
|
13772
14185
|
function enrichNetworkMeta(meta) {
|
|
@@ -13777,7 +14190,8 @@ function enrichNetworkMeta(meta) {
|
|
|
13777
14190
|
failureKind: meta.ok === false ? "http" : meta.failureKind
|
|
13778
14191
|
};
|
|
13779
14192
|
}
|
|
13780
|
-
|
|
14193
|
+
const hasTransportSignal = !!meta.errorName || !!meta.errorMessage || !!meta.aborted || meta.failureKind === "abort" || meta.failureKind === "timeout" || meta.failureKind === "network";
|
|
14194
|
+
if (hasTransportSignal) {
|
|
13781
14195
|
const failureKind = meta.failureKind === "abort" || meta.failureKind === "timeout" || meta.failureKind === "network" ? meta.failureKind : classifyTransportFailure({
|
|
13782
14196
|
aborted: meta.aborted,
|
|
13783
14197
|
errorName: meta.errorName
|
|
@@ -13790,10 +14204,13 @@ function enrichNetworkMeta(meta) {
|
|
|
13790
14204
|
}
|
|
13791
14205
|
return meta;
|
|
13792
14206
|
}
|
|
13793
|
-
function networkUrlParts(rawUrl, includeQuery) {
|
|
13794
|
-
const
|
|
14207
|
+
function networkUrlParts(rawUrl, includeQuery, pageOrigin) {
|
|
14208
|
+
const baseHref = pageOrigin || (typeof location !== "undefined" ? location.href : void 0);
|
|
14209
|
+
const parts = sanitizeNetworkUrl(rawUrl, { includeQuery, baseHref });
|
|
14210
|
+
const origin = resolveRequestOrigin(rawUrl, pageOrigin);
|
|
13795
14211
|
return {
|
|
13796
14212
|
url: parts.url,
|
|
14213
|
+
origin: origin || void 0,
|
|
13797
14214
|
hostname: parts.hostname,
|
|
13798
14215
|
pathname: parts.pathname,
|
|
13799
14216
|
...parts.search ? { search: parts.search } : {}
|
|
@@ -13809,14 +14226,22 @@ function installNetworkHook(options = {}) {
|
|
|
13809
14226
|
captureNetworkErrors: options.captureNetworkErrors ?? true,
|
|
13810
14227
|
failedRequestStatusCodes: options.failedRequestStatusCodes ?? [[500, 599]],
|
|
13811
14228
|
failedRequestIgnoreUrls: options.failedRequestIgnoreUrls ?? [],
|
|
14229
|
+
networkErrorOrigins: options.networkErrorOrigins ?? [],
|
|
14230
|
+
pageOrigin: options.pageOrigin,
|
|
13812
14231
|
talariaBaseUrl: options.talariaBaseUrl
|
|
13813
14232
|
};
|
|
13814
14233
|
const includeQuery = options.captureRequestQueryParameters ?? options.includeNetworkUrlQuery ?? false;
|
|
13815
14234
|
const handleMeta = (meta) => {
|
|
13816
14235
|
const { rawUrl, ...rest } = meta;
|
|
14236
|
+
const parts = networkUrlParts(rawUrl, includeQuery, matchOpts.pageOrigin);
|
|
14237
|
+
const party = classifyNetworkParty(
|
|
14238
|
+
parts.origin || "",
|
|
14239
|
+
matchOpts.pageOrigin
|
|
14240
|
+
);
|
|
13817
14241
|
const enriched = enrichNetworkMeta({
|
|
13818
14242
|
...rest,
|
|
13819
|
-
...
|
|
14243
|
+
...parts,
|
|
14244
|
+
party
|
|
13820
14245
|
});
|
|
13821
14246
|
try {
|
|
13822
14247
|
emitNetwork(enriched);
|
|
@@ -13836,6 +14261,7 @@ function installNetworkHook(options = {}) {
|
|
|
13836
14261
|
const rawUrl = typeof input2 === "string" ? input2 : input2 instanceof URL ? input2.toString() : input2.url;
|
|
13837
14262
|
try {
|
|
13838
14263
|
const response = await originalFetch(input2, init);
|
|
14264
|
+
const opaque = response.type === "opaque" || response.type === "opaqueredirect";
|
|
13839
14265
|
handleMeta({
|
|
13840
14266
|
method,
|
|
13841
14267
|
rawUrl,
|
|
@@ -13843,7 +14269,8 @@ function installNetworkHook(options = {}) {
|
|
|
13843
14269
|
transport: "fetch",
|
|
13844
14270
|
status: response.status,
|
|
13845
14271
|
durationMs: Date.now() - started,
|
|
13846
|
-
|
|
14272
|
+
// Opaque responses resolve successfully with status 0 — not a failure.
|
|
14273
|
+
ok: opaque ? true : response.ok
|
|
13847
14274
|
});
|
|
13848
14275
|
return response;
|
|
13849
14276
|
} catch (error) {
|
|
@@ -13905,7 +14332,7 @@ function installNetworkHook(options = {}) {
|
|
|
13905
14332
|
transport: "xhr",
|
|
13906
14333
|
status,
|
|
13907
14334
|
durationMs: Date.now() - (this.__talariaStarted ?? Date.now()),
|
|
13908
|
-
ok: status
|
|
14335
|
+
ok: isHttpOkStatus(status),
|
|
13909
14336
|
...transportFail ? {
|
|
13910
14337
|
failureKind,
|
|
13911
14338
|
errorName,
|
|
@@ -13914,7 +14341,7 @@ function installNetworkHook(options = {}) {
|
|
|
13914
14341
|
} : {}
|
|
13915
14342
|
});
|
|
13916
14343
|
};
|
|
13917
|
-
this.addEventListener("loadend", onDone);
|
|
14344
|
+
this.addEventListener("loadend", onDone, { once: true });
|
|
13918
14345
|
return originalSend.call(this, body);
|
|
13919
14346
|
};
|
|
13920
14347
|
}
|
|
@@ -13926,10 +14353,26 @@ function installNetworkHook(options = {}) {
|
|
|
13926
14353
|
}
|
|
13927
14354
|
|
|
13928
14355
|
// src/client.ts
|
|
14356
|
+
var PLATFORM_JAVASCRIPT = "javascript";
|
|
14357
|
+
var EXTRA_LOCATION_KEYS = /* @__PURE__ */ new Set([
|
|
14358
|
+
"exception_class",
|
|
14359
|
+
"file",
|
|
14360
|
+
"line",
|
|
14361
|
+
"code",
|
|
14362
|
+
"filename",
|
|
14363
|
+
"lineno",
|
|
14364
|
+
"colno"
|
|
14365
|
+
]);
|
|
14366
|
+
function networkExceptionClass(failure) {
|
|
14367
|
+
if (failure.failureKind === "http") return "HttpError";
|
|
14368
|
+
if (failure.failureKind === "timeout") return "TimeoutError";
|
|
14369
|
+
return "NetworkError";
|
|
14370
|
+
}
|
|
13929
14371
|
function networkFailureTags(failure) {
|
|
13930
14372
|
return {
|
|
13931
14373
|
"http.method": failure.method || "GET",
|
|
13932
14374
|
"network.failure_kind": failure.failureKind ?? "network",
|
|
14375
|
+
...failure.party ? { "network.party": failure.party } : {},
|
|
13933
14376
|
...failure.transport ? { "network.transport": failure.transport } : {},
|
|
13934
14377
|
...failure.errorName ? { "network.error_name": failure.errorName } : {}
|
|
13935
14378
|
};
|
|
@@ -13939,6 +14382,7 @@ function networkFailureExtra(failure) {
|
|
|
13939
14382
|
method: failure.method || "GET",
|
|
13940
14383
|
url: failure.url || "(unknown url)"
|
|
13941
14384
|
};
|
|
14385
|
+
if (failure.origin) http.origin = failure.origin;
|
|
13942
14386
|
if (failure.hostname) http.hostname = failure.hostname;
|
|
13943
14387
|
if (failure.pathname) http.pathname = failure.pathname;
|
|
13944
14388
|
if (failure.search) http.search = failure.search;
|
|
@@ -13951,14 +14395,69 @@ function networkFailureExtra(failure) {
|
|
|
13951
14395
|
};
|
|
13952
14396
|
if (failure.errorName) fail.name = failure.errorName;
|
|
13953
14397
|
if (failure.errorMessage) fail.message = failure.errorMessage;
|
|
14398
|
+
const statusCode = typeof failure.status === "number" && failure.status > 0 ? failure.status : null;
|
|
13954
14399
|
return {
|
|
13955
14400
|
http,
|
|
13956
14401
|
failure: fail,
|
|
14402
|
+
network: {
|
|
14403
|
+
party: failure.party ?? "third_party",
|
|
14404
|
+
durationMs: failure.durationMs,
|
|
14405
|
+
aborted: failure.aborted ?? false,
|
|
14406
|
+
ok: failure.ok ?? false
|
|
14407
|
+
},
|
|
14408
|
+
// Top-level for server fingerprint compatibility (status only —
|
|
14409
|
+
// exception type lives on first-class `exception.values[0].type`).
|
|
14410
|
+
status_code: statusCode,
|
|
13957
14411
|
durationMs: failure.durationMs,
|
|
13958
14412
|
aborted: failure.aborted ?? false,
|
|
13959
14413
|
ok: failure.ok ?? false
|
|
13960
14414
|
};
|
|
13961
14415
|
}
|
|
14416
|
+
function networkExceptionData(failure, message) {
|
|
14417
|
+
return {
|
|
14418
|
+
values: [
|
|
14419
|
+
{
|
|
14420
|
+
type: networkExceptionClass(failure),
|
|
14421
|
+
value: message,
|
|
14422
|
+
mechanism: {
|
|
14423
|
+
type: "http",
|
|
14424
|
+
handled: true,
|
|
14425
|
+
synthetic: true
|
|
14426
|
+
}
|
|
14427
|
+
}
|
|
14428
|
+
]
|
|
14429
|
+
};
|
|
14430
|
+
}
|
|
14431
|
+
function scrubLegacyExceptionExtra(extra) {
|
|
14432
|
+
if (!extra) return void 0;
|
|
14433
|
+
const out = {};
|
|
14434
|
+
for (const [key, value] of Object.entries(extra)) {
|
|
14435
|
+
if (EXTRA_LOCATION_KEYS.has(key)) continue;
|
|
14436
|
+
out[key] = value;
|
|
14437
|
+
}
|
|
14438
|
+
return Object.keys(out).length ? out : void 0;
|
|
14439
|
+
}
|
|
14440
|
+
function buildExceptionFromError(err, context, inAppOptions) {
|
|
14441
|
+
const mechanism = context?.mechanism ?? {
|
|
14442
|
+
type: "generic",
|
|
14443
|
+
handled: true
|
|
14444
|
+
};
|
|
14445
|
+
const stacktrace = applySourceLocation(
|
|
14446
|
+
parseStackTrace(err.stack, inAppOptions),
|
|
14447
|
+
context?.source,
|
|
14448
|
+
inAppOptions
|
|
14449
|
+
);
|
|
14450
|
+
return {
|
|
14451
|
+
values: [
|
|
14452
|
+
{
|
|
14453
|
+
type: err.name || "Error",
|
|
14454
|
+
value: err.message || err.name || "Error",
|
|
14455
|
+
mechanism,
|
|
14456
|
+
...stacktrace ? { stacktrace } : {}
|
|
14457
|
+
}
|
|
14458
|
+
]
|
|
14459
|
+
};
|
|
14460
|
+
}
|
|
13962
14461
|
function mergeNetworkFailureContext(context, failure) {
|
|
13963
14462
|
return {
|
|
13964
14463
|
...context,
|
|
@@ -13995,13 +14494,17 @@ function resolveOptions(options) {
|
|
|
13995
14494
|
inlineStylesheet: options.inlineStylesheet ?? false,
|
|
13996
14495
|
blockSelector: options.blockSelector ?? "",
|
|
13997
14496
|
userId: options.userId,
|
|
13998
|
-
tags: options.tags,
|
|
14497
|
+
tags: mergeTags(options.tags),
|
|
13999
14498
|
disableDefaultIntegrations: options.disableDefaultIntegrations ?? false,
|
|
14000
14499
|
captureFailedRequests: options.captureFailedRequests ?? true,
|
|
14001
14500
|
captureNetworkErrors: options.captureNetworkErrors ?? true,
|
|
14501
|
+
networkErrorOrigins: options.networkErrorOrigins ?? [],
|
|
14002
14502
|
includeNetworkUrlQuery: options.captureRequestQueryParameters ?? options.includeNetworkUrlQuery ?? false,
|
|
14003
14503
|
failedRequestStatusCodes: options.failedRequestStatusCodes ?? [[500, 599]],
|
|
14004
|
-
failedRequestIgnoreUrls: options.failedRequestIgnoreUrls ?? []
|
|
14504
|
+
failedRequestIgnoreUrls: options.failedRequestIgnoreUrls ?? [],
|
|
14505
|
+
inAppAllowUrls: options.inAppAllowUrls ?? [],
|
|
14506
|
+
inAppDenyUrls: options.inAppDenyUrls ?? [],
|
|
14507
|
+
inAppOrigins: options.inAppOrigins ?? []
|
|
14005
14508
|
};
|
|
14006
14509
|
}
|
|
14007
14510
|
var RECENT_NETWORK_FAILURE_MS = 5e3;
|
|
@@ -14128,6 +14631,8 @@ var TalariaClient = class {
|
|
|
14128
14631
|
installNetworkHook({
|
|
14129
14632
|
captureFailedRequests: this.options.captureFailedRequests,
|
|
14130
14633
|
captureNetworkErrors: this.options.captureNetworkErrors,
|
|
14634
|
+
networkErrorOrigins: this.options.networkErrorOrigins,
|
|
14635
|
+
pageOrigin: typeof location !== "undefined" ? location.origin : void 0,
|
|
14131
14636
|
includeNetworkUrlQuery: this.options.includeNetworkUrlQuery,
|
|
14132
14637
|
failedRequestStatusCodes: this.options.failedRequestStatusCodes,
|
|
14133
14638
|
failedRequestIgnoreUrls: this.options.failedRequestIgnoreUrls,
|
|
@@ -14146,17 +14651,21 @@ var TalariaClient = class {
|
|
|
14146
14651
|
failureKind: "http",
|
|
14147
14652
|
aborted: false
|
|
14148
14653
|
};
|
|
14149
|
-
|
|
14150
|
-
|
|
14151
|
-
|
|
14152
|
-
|
|
14654
|
+
const message = `HTTP ${status}: ${method} ${url}`;
|
|
14655
|
+
void this.capture({
|
|
14656
|
+
message,
|
|
14657
|
+
level: status >= 500 ? "error" : "warning",
|
|
14658
|
+
title: networkExceptionClass(enriched),
|
|
14659
|
+
exception: networkExceptionData(enriched, message),
|
|
14660
|
+
platform: PLATFORM_JAVASCRIPT,
|
|
14661
|
+
context: {
|
|
14153
14662
|
tags: {
|
|
14154
14663
|
...networkFailureTags(enriched),
|
|
14155
14664
|
"http.status_code": String(status)
|
|
14156
14665
|
},
|
|
14157
14666
|
extra: networkFailureExtra(enriched)
|
|
14158
14667
|
}
|
|
14159
|
-
);
|
|
14668
|
+
});
|
|
14160
14669
|
},
|
|
14161
14670
|
onNetworkError: (meta) => {
|
|
14162
14671
|
this.rememberNetworkFailure(meta, { promoted: true });
|
|
@@ -14164,14 +14673,18 @@ var TalariaClient = class {
|
|
|
14164
14673
|
const url = meta.url || "(unknown url)";
|
|
14165
14674
|
const errLabel = meta.errorName && meta.errorMessage ? `${meta.errorName}: ${meta.errorMessage}` : meta.errorMessage || meta.errorName || "Failed to fetch";
|
|
14166
14675
|
const prefix = meta.failureKind === "timeout" ? "Timeout error" : "Network error";
|
|
14167
|
-
|
|
14168
|
-
|
|
14169
|
-
|
|
14170
|
-
|
|
14676
|
+
const message = `${prefix}: ${method} ${url} \u2014 ${errLabel}`;
|
|
14677
|
+
void this.capture({
|
|
14678
|
+
message,
|
|
14679
|
+
level: "error",
|
|
14680
|
+
title: networkExceptionClass(meta),
|
|
14681
|
+
exception: networkExceptionData(meta, message),
|
|
14682
|
+
platform: PLATFORM_JAVASCRIPT,
|
|
14683
|
+
context: {
|
|
14171
14684
|
tags: networkFailureTags(meta),
|
|
14172
14685
|
extra: networkFailureExtra(meta)
|
|
14173
14686
|
}
|
|
14174
|
-
);
|
|
14687
|
+
});
|
|
14175
14688
|
}
|
|
14176
14689
|
}),
|
|
14177
14690
|
installVisibilityResumeHook(() => this.onForegroundResume())
|
|
@@ -14208,7 +14721,7 @@ var TalariaClient = class {
|
|
|
14208
14721
|
if (this.capturing || this.ingestDisabled) return;
|
|
14209
14722
|
const err = error instanceof Error ? error : new Error(typeof error === "string" ? error : "Unknown error");
|
|
14210
14723
|
if (isAbortError(err)) return;
|
|
14211
|
-
const filename =
|
|
14724
|
+
const filename = context?.source?.filename;
|
|
14212
14725
|
if (isBrowserExtensionNoise({
|
|
14213
14726
|
message: err.message,
|
|
14214
14727
|
stack: err.stack,
|
|
@@ -14221,6 +14734,7 @@ var TalariaClient = class {
|
|
|
14221
14734
|
}
|
|
14222
14735
|
const correlated = this.consumeCorrelatedNetworkFailure(err);
|
|
14223
14736
|
if (correlated?.promoted) return;
|
|
14737
|
+
if (correlated && correlated.party === "third_party") return;
|
|
14224
14738
|
const mergedContext = correlated ? mergeNetworkFailureContext(context, correlated) : context;
|
|
14225
14739
|
this.capturing = true;
|
|
14226
14740
|
try {
|
|
@@ -14229,6 +14743,12 @@ var TalariaClient = class {
|
|
|
14229
14743
|
level: "error",
|
|
14230
14744
|
title: err.name || "Error",
|
|
14231
14745
|
stackTrace: err.stack,
|
|
14746
|
+
exception: buildExceptionFromError(
|
|
14747
|
+
err,
|
|
14748
|
+
mergedContext,
|
|
14749
|
+
this.inAppFrameOptions()
|
|
14750
|
+
),
|
|
14751
|
+
platform: PLATFORM_JAVASCRIPT,
|
|
14232
14752
|
context: mergedContext
|
|
14233
14753
|
});
|
|
14234
14754
|
} finally {
|
|
@@ -14244,6 +14764,13 @@ var TalariaClient = class {
|
|
|
14244
14764
|
context
|
|
14245
14765
|
});
|
|
14246
14766
|
}
|
|
14767
|
+
/**
|
|
14768
|
+
* Returns a scoped capture facade that merges [tags] into every event.
|
|
14769
|
+
* Nested `withTags` calls merge further (later keys win).
|
|
14770
|
+
*/
|
|
14771
|
+
withTags(tags) {
|
|
14772
|
+
return createScopedTalaria(this, mergeTags(tags));
|
|
14773
|
+
}
|
|
14247
14774
|
async flush(opts) {
|
|
14248
14775
|
if (!this.options || !this.transport || this.closed) return;
|
|
14249
14776
|
const keepalive = opts?.keepalive ?? false;
|
|
@@ -14408,13 +14935,17 @@ var TalariaClient = class {
|
|
|
14408
14935
|
}
|
|
14409
14936
|
const queuedMs = Math.max(0, Date.now() - occurredAt.getTime());
|
|
14410
14937
|
const tags = applyReplayCaptureTags(
|
|
14411
|
-
|
|
14412
|
-
|
|
14413
|
-
|
|
14414
|
-
|
|
14415
|
-
|
|
14938
|
+
mergeTags(
|
|
14939
|
+
this.browserContext ? browserContextTags(this.browserContext) : {},
|
|
14940
|
+
this.options.tags,
|
|
14941
|
+
args.context?.tags
|
|
14942
|
+
),
|
|
14416
14943
|
errorClipOutcome
|
|
14417
14944
|
);
|
|
14945
|
+
warnSuspiciousTags(tags, this.options.environment);
|
|
14946
|
+
const scrubbedContextExtra = scrubLegacyExceptionExtra(
|
|
14947
|
+
args.context?.extra
|
|
14948
|
+
);
|
|
14418
14949
|
const extra = mergeReplayCaptureExtra(
|
|
14419
14950
|
{
|
|
14420
14951
|
...this.browserContext ? {
|
|
@@ -14436,7 +14967,7 @@ var TalariaClient = class {
|
|
|
14436
14967
|
// Time spent in capture() before ingest (mostly replay flush).
|
|
14437
14968
|
...queuedMs >= 50 ? { queuedMs } : {}
|
|
14438
14969
|
},
|
|
14439
|
-
...
|
|
14970
|
+
...scrubbedContextExtra ?? {}
|
|
14440
14971
|
},
|
|
14441
14972
|
errorClipOutcome
|
|
14442
14973
|
);
|
|
@@ -14448,6 +14979,8 @@ var TalariaClient = class {
|
|
|
14448
14979
|
eventType: levelToEventType(args.level),
|
|
14449
14980
|
title: args.title ?? args.context?.title,
|
|
14450
14981
|
stackTrace: args.stackTrace,
|
|
14982
|
+
exception: args.exception,
|
|
14983
|
+
platform: args.platform,
|
|
14451
14984
|
release: this.options.release,
|
|
14452
14985
|
userId: args.context?.userId ?? this.options.userId,
|
|
14453
14986
|
sessionId: this.sessionId ?? void 0,
|
|
@@ -14697,12 +15230,36 @@ var TalariaClient = class {
|
|
|
14697
15230
|
this.resetToBufferMode();
|
|
14698
15231
|
}
|
|
14699
15232
|
}
|
|
15233
|
+
inAppFrameOptions() {
|
|
15234
|
+
const opts = this.options;
|
|
15235
|
+
let pageOrigin;
|
|
15236
|
+
try {
|
|
15237
|
+
pageOrigin = resolvePageOrigin(
|
|
15238
|
+
typeof window !== "undefined" ? window.location?.origin : void 0
|
|
15239
|
+
);
|
|
15240
|
+
} catch {
|
|
15241
|
+
pageOrigin = void 0;
|
|
15242
|
+
}
|
|
15243
|
+
return {
|
|
15244
|
+
pageOrigin,
|
|
15245
|
+
allowUrls: opts?.inAppAllowUrls,
|
|
15246
|
+
denyUrls: opts?.inAppDenyUrls,
|
|
15247
|
+
inAppOrigins: opts?.inAppOrigins
|
|
15248
|
+
};
|
|
15249
|
+
}
|
|
14700
15250
|
pruneRecentNetworkFailures(now = Date.now()) {
|
|
14701
15251
|
this.recentNetworkFailures = this.recentNetworkFailures.filter(
|
|
14702
15252
|
(f) => now - f.at <= RECENT_NETWORK_FAILURE_MS
|
|
14703
15253
|
);
|
|
14704
15254
|
}
|
|
14705
15255
|
rememberNetworkFailure(meta, opts) {
|
|
15256
|
+
if (this.options) {
|
|
15257
|
+
const ignore = buildFailedRequestIgnoreUrls(
|
|
15258
|
+
this.options.failedRequestIgnoreUrls,
|
|
15259
|
+
this.options.baseUrl
|
|
15260
|
+
);
|
|
15261
|
+
if (urlMatchesIgnoreList(meta.url || "", ignore)) return;
|
|
15262
|
+
}
|
|
14706
15263
|
const now = Date.now();
|
|
14707
15264
|
this.pruneRecentNetworkFailures(now);
|
|
14708
15265
|
for (let i = this.recentNetworkFailures.length - 1; i >= 0; i--) {
|
|
@@ -14713,6 +15270,8 @@ var TalariaClient = class {
|
|
|
14713
15270
|
existing.errorName = meta.errorName ?? existing.errorName;
|
|
14714
15271
|
existing.aborted = meta.aborted ?? existing.aborted;
|
|
14715
15272
|
existing.failureKind = meta.failureKind ?? existing.failureKind;
|
|
15273
|
+
existing.party = meta.party ?? existing.party;
|
|
15274
|
+
existing.origin = meta.origin ?? existing.origin;
|
|
14716
15275
|
return;
|
|
14717
15276
|
}
|
|
14718
15277
|
}
|
|
@@ -14723,11 +15282,12 @@ var TalariaClient = class {
|
|
|
14723
15282
|
});
|
|
14724
15283
|
}
|
|
14725
15284
|
/**
|
|
14726
|
-
* Find a recent transport failure for a bare fetch TypeError.
|
|
15285
|
+
* Find a recent transport failure for a bare fetch TypeError / TimeoutError.
|
|
14727
15286
|
* Consumes the entry so a later duplicate path cannot reuse it.
|
|
14728
15287
|
*/
|
|
14729
15288
|
consumeCorrelatedNetworkFailure(error) {
|
|
14730
|
-
if (!
|
|
15289
|
+
if (!isCorrelatableTransportError(error)) return null;
|
|
15290
|
+
const wantKind = isTimeoutError(error) ? "timeout" : "network";
|
|
14731
15291
|
const now = Date.now();
|
|
14732
15292
|
this.pruneRecentNetworkFailures(now);
|
|
14733
15293
|
const takeAt = (index2) => {
|
|
@@ -14736,14 +15296,14 @@ var TalariaClient = class {
|
|
|
14736
15296
|
};
|
|
14737
15297
|
for (let i = this.recentNetworkFailures.length - 1; i >= 0; i--) {
|
|
14738
15298
|
const failure = this.recentNetworkFailures[i];
|
|
14739
|
-
if (failure.aborted || failure.failureKind !==
|
|
15299
|
+
if (failure.aborted || failure.failureKind !== wantKind) continue;
|
|
14740
15300
|
if (failure.errorMessage && failure.errorMessage === error.message) {
|
|
14741
15301
|
return takeAt(i);
|
|
14742
15302
|
}
|
|
14743
15303
|
}
|
|
14744
15304
|
for (let i = this.recentNetworkFailures.length - 1; i >= 0; i--) {
|
|
14745
15305
|
const failure = this.recentNetworkFailures[i];
|
|
14746
|
-
if (failure.aborted || failure.failureKind !==
|
|
15306
|
+
if (failure.aborted || failure.failureKind !== wantKind) continue;
|
|
14747
15307
|
return takeAt(i);
|
|
14748
15308
|
}
|
|
14749
15309
|
return null;
|
|
@@ -14761,7 +15321,8 @@ var TalariaClient = class {
|
|
|
14761
15321
|
return;
|
|
14762
15322
|
}
|
|
14763
15323
|
void this.captureException(error, {
|
|
14764
|
-
|
|
15324
|
+
mechanism: { type: "onerror", handled: false },
|
|
15325
|
+
source: {
|
|
14765
15326
|
filename: event.filename,
|
|
14766
15327
|
lineno: event.lineno,
|
|
14767
15328
|
colno: event.colno
|
|
@@ -14783,7 +15344,9 @@ var TalariaClient = class {
|
|
|
14783
15344
|
})) {
|
|
14784
15345
|
return;
|
|
14785
15346
|
}
|
|
14786
|
-
void this.captureException(reason
|
|
15347
|
+
void this.captureException(reason, {
|
|
15348
|
+
mechanism: { type: "unhandledrejection", handled: false }
|
|
15349
|
+
});
|
|
14787
15350
|
};
|
|
14788
15351
|
window.addEventListener("error", onError);
|
|
14789
15352
|
window.addEventListener("unhandledrejection", onRejection);
|
|
@@ -15045,6 +15608,23 @@ var TalariaClient = class {
|
|
|
15045
15608
|
}
|
|
15046
15609
|
}
|
|
15047
15610
|
};
|
|
15611
|
+
function createScopedTalaria(client2, scopeTags) {
|
|
15612
|
+
const mergeContext = (context) => ({
|
|
15613
|
+
...context,
|
|
15614
|
+
tags: mergeTags(scopeTags, context?.tags)
|
|
15615
|
+
});
|
|
15616
|
+
return {
|
|
15617
|
+
captureException(error, context) {
|
|
15618
|
+
return client2.captureException(error, mergeContext(context));
|
|
15619
|
+
},
|
|
15620
|
+
captureMessage(message, level, context) {
|
|
15621
|
+
return client2.captureMessage(message, level, mergeContext(context));
|
|
15622
|
+
},
|
|
15623
|
+
withTags(tags) {
|
|
15624
|
+
return createScopedTalaria(client2, mergeTags(scopeTags, tags));
|
|
15625
|
+
}
|
|
15626
|
+
};
|
|
15627
|
+
}
|
|
15048
15628
|
|
|
15049
15629
|
// src/index.ts
|
|
15050
15630
|
var client = new TalariaClient();
|
|
@@ -15058,6 +15638,9 @@ var Talaria = {
|
|
|
15058
15638
|
captureMessage(message, level, context) {
|
|
15059
15639
|
return client.captureMessage(message, level, context);
|
|
15060
15640
|
},
|
|
15641
|
+
withTags(tags) {
|
|
15642
|
+
return client.withTags(tags);
|
|
15643
|
+
},
|
|
15061
15644
|
getReplayId() {
|
|
15062
15645
|
return client.getReplayId();
|
|
15063
15646
|
},
|
|
@@ -15075,14 +15658,22 @@ export {
|
|
|
15075
15658
|
MAX_SEGMENTS_ERROR_CLIP,
|
|
15076
15659
|
REPLAY_CAPTURE_REASON_TAG,
|
|
15077
15660
|
REPLAY_CAPTURE_TAG,
|
|
15661
|
+
RESERVED_TAG_KEYS,
|
|
15078
15662
|
TARGET_COMPRESSED_SEGMENT_BYTES,
|
|
15079
15663
|
Talaria,
|
|
15080
15664
|
TalariaClient,
|
|
15665
|
+
applySourceLocation,
|
|
15081
15666
|
computeErrorClipDeadlineMs,
|
|
15082
15667
|
index_default as default,
|
|
15083
15668
|
fitCompressedPrefix,
|
|
15084
15669
|
isErrorClipBudgetExhausted,
|
|
15085
|
-
|
|
15670
|
+
isInAppFrame,
|
|
15671
|
+
mergeTags,
|
|
15672
|
+
normalizeTags,
|
|
15673
|
+
parseStackLine,
|
|
15674
|
+
parseStackTrace,
|
|
15675
|
+
planOversizedRetry,
|
|
15676
|
+
resolvePageOrigin
|
|
15086
15677
|
};
|
|
15087
15678
|
/*! Bundled license information:
|
|
15088
15679
|
|