@cross-deck/node 1.1.0 → 1.1.1

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/dist/index.cjs CHANGED
@@ -1084,13 +1084,21 @@ function isInAppFrame(filename) {
1084
1084
  if (/^internal[\\/]/.test(filename)) return false;
1085
1085
  return true;
1086
1086
  }
1087
- function fingerprintError(message, frames) {
1087
+ function fingerprintError(message, frames, location) {
1088
1088
  const inAppFrames = frames.filter((f) => f.in_app).slice(0, 3);
1089
- const key = [
1089
+ const parts = [
1090
1090
  (message || "").slice(0, 200),
1091
1091
  ...inAppFrames.map((f) => `${f.function}@${f.filename}:${f.lineno}`)
1092
- ].join("|");
1093
- return djb2Hex(key);
1092
+ ];
1093
+ if (inAppFrames.length === 0 && location) {
1094
+ const loc = [
1095
+ location.errorType ?? "",
1096
+ location.filename ?? "",
1097
+ location.lineno ?? ""
1098
+ ].join(":");
1099
+ if (loc !== "::") parts.push(loc);
1100
+ }
1101
+ return djb2Hex(parts.join("|"));
1094
1102
  }
1095
1103
  function djb2Hex(input) {
1096
1104
  let h = 5381;
@@ -1321,34 +1329,30 @@ var ErrorTracker = class {
1321
1329
  * runtime-agnostic.
1322
1330
  */
1323
1331
  buildFromUnknown(err, kind, level) {
1324
- if (err instanceof Error) {
1325
- const frames = parseStack(err.stack);
1326
- return {
1327
- timestamp: Date.now(),
1328
- kind,
1329
- level,
1330
- message: String(err.message).slice(0, 1024),
1331
- errorType: err.name,
1332
- frames,
1333
- rawStack: err.stack ?? null,
1334
- fingerprint: fingerprintError(err.message, frames),
1335
- breadcrumbs: this.opts.breadcrumbs.snapshot(),
1336
- context: this.opts.getContext(),
1337
- tags: this.opts.getTags()
1338
- };
1339
- }
1340
- const message = safeStringify3(err).slice(0, 1024);
1332
+ const payload = coerceErrorPayload(err);
1333
+ const message = (payload.message || "Unknown error").slice(0, 1024);
1334
+ const stack = err instanceof Error ? err.stack ?? null : null;
1335
+ const frames = parseStack(stack);
1336
+ const errorType = payload.errorType ?? null;
1337
+ const context = payload.extras ? { ...this.opts.getContext(), __error_extras: payload.extras } : this.opts.getContext();
1341
1338
  return {
1342
1339
  timestamp: Date.now(),
1343
1340
  kind,
1344
1341
  level,
1345
1342
  message,
1346
- errorType: null,
1347
- frames: [],
1348
- rawStack: null,
1349
- fingerprint: fingerprintError(message, []),
1343
+ errorType,
1344
+ frames,
1345
+ rawStack: stack,
1346
+ // Location fallback ensures distinct call sites stay separate
1347
+ // even when the message is generic and there are no parseable
1348
+ // frames (e.g. `throw "boom"` from a middleware).
1349
+ fingerprint: fingerprintError(message, frames, {
1350
+ filename: frames[0]?.filename ?? null,
1351
+ lineno: frames[0]?.lineno ?? null,
1352
+ errorType
1353
+ }),
1350
1354
  breadcrumbs: this.opts.breadcrumbs.snapshot(),
1351
- context: this.opts.getContext(),
1355
+ context,
1352
1356
  tags: this.opts.getTags()
1353
1357
  };
1354
1358
  }
@@ -1363,7 +1367,10 @@ var ErrorTracker = class {
1363
1367
  errorType: "HTTPError",
1364
1368
  frames: [],
1365
1369
  rawStack: null,
1366
- fingerprint: fingerprintError(`HTTP ${info.status} ${info.method}`, []),
1370
+ fingerprint: fingerprintError(`HTTP ${info.status} ${info.method}`, [], {
1371
+ filename: info.url,
1372
+ errorType: "HTTPError"
1373
+ }),
1367
1374
  breadcrumbs: this.opts.breadcrumbs.snapshot(),
1368
1375
  context: this.opts.getContext(),
1369
1376
  tags: this.opts.getTags(),
@@ -1466,16 +1473,151 @@ var ErrorTracker = class {
1466
1473
  }
1467
1474
  }
1468
1475
  };
1469
- function safeStringify3(v) {
1470
- if (v == null) return String(v);
1471
- if (typeof v === "string") return v;
1472
- if (typeof v === "number" || typeof v === "boolean") return String(v);
1476
+ function coerceErrorPayload(v) {
1477
+ if (v === null) return { message: "(thrown: null)", errorType: null, extras: null };
1478
+ if (v === void 0) return { message: "(thrown: undefined)", errorType: null, extras: null };
1479
+ if (typeof v === "string") {
1480
+ return { message: v, errorType: null, extras: null };
1481
+ }
1482
+ if (typeof v === "number" || typeof v === "boolean" || typeof v === "bigint") {
1483
+ return { message: String(v), errorType: typeof v, extras: null };
1484
+ }
1485
+ if (typeof v === "symbol") {
1486
+ return { message: v.toString(), errorType: "symbol", extras: null };
1487
+ }
1488
+ if (typeof v === "function") {
1489
+ return { message: `(thrown function: ${v.name || "anonymous"})`, errorType: "function", extras: null };
1490
+ }
1491
+ if (v instanceof Error) {
1492
+ const errorType = v.name || v.constructor?.name || "Error";
1493
+ const message = typeof v.message === "string" && v.message.length > 0 ? v.message : safeToString(v) || errorType;
1494
+ const extras = {};
1495
+ const causeChain = collectCauseChain(v);
1496
+ if (causeChain.length > 0) extras.cause = causeChain;
1497
+ const aggErrors = v.errors;
1498
+ if (Array.isArray(aggErrors)) {
1499
+ extras.aggregatedErrors = aggErrors.slice(0, 10).map((inner) => {
1500
+ if (inner instanceof Error) {
1501
+ return { name: inner.name || "Error", message: inner.message || "" };
1502
+ }
1503
+ return { name: "non-Error", message: safeToString(inner) };
1504
+ });
1505
+ }
1506
+ for (const key of [
1507
+ "code",
1508
+ "errno",
1509
+ "syscall",
1510
+ "path",
1511
+ "status",
1512
+ "statusCode",
1513
+ "response",
1514
+ "data",
1515
+ "detail",
1516
+ "details"
1517
+ ]) {
1518
+ const val = v[key];
1519
+ if (val !== void 0 && typeof val !== "function") {
1520
+ extras[key] = safeClone(val);
1521
+ }
1522
+ }
1523
+ for (const key of Object.keys(v)) {
1524
+ if (key === "message" || key === "stack" || key === "name" || key === "cause" || key === "errors") continue;
1525
+ if (key in extras) continue;
1526
+ const val = v[key];
1527
+ if (typeof val === "function") continue;
1528
+ extras[key] = safeClone(val);
1529
+ }
1530
+ return {
1531
+ message,
1532
+ errorType,
1533
+ extras: Object.keys(extras).length > 0 ? extras : null
1534
+ };
1535
+ }
1536
+ if (typeof Response !== "undefined" && v instanceof Response) {
1537
+ return {
1538
+ message: `HTTP ${v.status} ${v.statusText || ""}${v.url ? ` ${v.url}` : ""}`.trim(),
1539
+ errorType: "Response",
1540
+ extras: { status: v.status, statusText: v.statusText, url: v.url, type: v.type }
1541
+ };
1542
+ }
1543
+ if (typeof v === "object") {
1544
+ const obj = v;
1545
+ const ctorName = obj.constructor && typeof obj.constructor === "function" && obj.constructor.name || null;
1546
+ const ownMessage = typeof obj.message === "string" && obj.message ? obj.message : null;
1547
+ const ownName = typeof obj.name === "string" && obj.name ? obj.name : null;
1548
+ let jsonForm = null;
1549
+ try {
1550
+ const serialised = JSON.stringify(obj);
1551
+ jsonForm = serialised === "{}" ? null : serialised;
1552
+ } catch {
1553
+ jsonForm = null;
1554
+ }
1555
+ const fallbackString = safeToString(obj);
1556
+ const message = ownMessage ?? jsonForm ?? (fallbackString && fallbackString !== "[object Object]" ? fallbackString : null) ?? (ctorName ? `(thrown ${ctorName} with no message)` : "(thrown object with no message)");
1557
+ const errorType = ownName ?? ctorName ?? null;
1558
+ const extras = {};
1559
+ let count = 0;
1560
+ for (const key of Object.keys(obj)) {
1561
+ if (count >= 20) break;
1562
+ if (key === "message" || key === "name") continue;
1563
+ const val = obj[key];
1564
+ if (typeof val === "function") continue;
1565
+ extras[key] = safeClone(val);
1566
+ count++;
1567
+ }
1568
+ return {
1569
+ message,
1570
+ errorType,
1571
+ extras: Object.keys(extras).length > 0 ? extras : null
1572
+ };
1573
+ }
1574
+ return { message: safeToString(v) || "(unstringifiable thrown value)", errorType: null, extras: null };
1575
+ }
1576
+ function collectCauseChain(err) {
1577
+ const out = [];
1578
+ let cur = err.cause;
1579
+ let depth = 0;
1580
+ while (cur != null && depth < 5) {
1581
+ if (cur instanceof Error) {
1582
+ out.push({ name: cur.name || "Error", message: cur.message || "" });
1583
+ cur = cur.cause;
1584
+ } else {
1585
+ out.push({ name: "non-Error", message: safeToString(cur) });
1586
+ cur = null;
1587
+ }
1588
+ depth++;
1589
+ }
1590
+ return out;
1591
+ }
1592
+ function safeToString(v) {
1593
+ try {
1594
+ const s = Object.prototype.toString.call(v);
1595
+ if (s !== "[object Object]") return s;
1596
+ const own = v?.toString;
1597
+ if (typeof own === "function" && own !== Object.prototype.toString) {
1598
+ const r = own.call(v);
1599
+ if (typeof r === "string") return r;
1600
+ }
1601
+ return s;
1602
+ } catch {
1603
+ return "(throwing toString)";
1604
+ }
1605
+ }
1606
+ function safeClone(v) {
1607
+ if (v == null) return v;
1608
+ const t = typeof v;
1609
+ if (t === "string" || t === "number" || t === "boolean") return v;
1610
+ if (t === "bigint") return String(v);
1473
1611
  try {
1474
- return JSON.stringify(v);
1612
+ const s = JSON.stringify(v);
1613
+ return s === void 0 ? safeToString(v) : JSON.parse(s);
1475
1614
  } catch {
1476
- return Object.prototype.toString.call(v);
1615
+ return safeToString(v);
1477
1616
  }
1478
1617
  }
1618
+ function safeStringify3(v) {
1619
+ return coerceErrorPayload(v).message;
1620
+ }
1479
1621
 
1480
1622
  // src/runtime-info.ts
1481
1623
  var import_node_os = require("os");