@djangocfg/monitor 2.1.225 → 2.1.227
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/client.cjs +72 -13
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +1 -0
- package/dist/client.d.ts +1 -0
- package/dist/client.mjs +72 -13
- package/dist/client.mjs.map +1 -1
- package/dist/index.cjs +3 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.mjs +3 -2
- package/dist/index.mjs.map +1 -1
- package/dist/server.cjs +3 -2
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +1 -0
- package/dist/server.d.ts +1 -0
- package/dist/server.mjs +3 -2
- package/dist/server.mjs.map +1 -1
- package/package.json +2 -2
- package/src/_api/generated/cfg_monitor/_utils/schemas/FrontendEventIngestRequest.schema.ts +2 -1
- package/src/_api/generated/cfg_monitor/monitor/models.ts +1 -0
- package/src/_api/generated/cfg_monitor/schema.json +6 -1
- package/src/client/capture/console.ts +11 -5
- package/src/client/capture/js-errors.ts +46 -3
- package/src/client/capture/validation.ts +2 -1
- package/src/client/store/index.ts +18 -1
package/dist/client.mjs
CHANGED
|
@@ -1127,7 +1127,7 @@ var FrontendEventIngestRequestSchema = z.object({
|
|
|
1127
1127
|
event_type: z.nativeEnum(FrontendEventIngestRequestEventType),
|
|
1128
1128
|
message: z.string().min(1).max(5e3),
|
|
1129
1129
|
level: z.nativeEnum(FrontendEventIngestRequestLevel).optional(),
|
|
1130
|
-
stack_trace: z.string().max(
|
|
1130
|
+
stack_trace: z.string().max(1e4).optional(),
|
|
1131
1131
|
url: z.string().max(2e3).optional(),
|
|
1132
1132
|
fingerprint: z.string().max(64).optional(),
|
|
1133
1133
|
http_status: z.number().int().nullable().optional(),
|
|
@@ -1138,7 +1138,8 @@ var FrontendEventIngestRequestSchema = z.object({
|
|
|
1138
1138
|
browser_fingerprint: z.string().max(64).optional(),
|
|
1139
1139
|
extra: z.record(z.string(), z.any()).optional(),
|
|
1140
1140
|
project_name: z.string().max(100).optional(),
|
|
1141
|
-
environment: z.string().max(20).optional()
|
|
1141
|
+
environment: z.string().max(20).optional(),
|
|
1142
|
+
build_id: z.string().max(100).optional()
|
|
1142
1143
|
});
|
|
1143
1144
|
|
|
1144
1145
|
// src/_api/generated/cfg_monitor/_utils/schemas/IngestBatchRequest.schema.ts
|
|
@@ -1345,7 +1346,22 @@ var monitorStore = createStore((set, get) => ({
|
|
|
1345
1346
|
push(event) {
|
|
1346
1347
|
const { config, buffer } = get();
|
|
1347
1348
|
const maxSize = config.maxBufferSize ?? 20;
|
|
1348
|
-
const
|
|
1349
|
+
const sanitized = {
|
|
1350
|
+
...event,
|
|
1351
|
+
// Enforce field size limits before buffering (last-resort backstop)
|
|
1352
|
+
message: event.message && event.message.length > 4997 ? event.message.slice(0, 4997) + "..." : event.message,
|
|
1353
|
+
stack_trace: event.stack_trace && event.stack_trace.length > 1e4 ? event.stack_trace.slice(0, 9997) + "..." : event.stack_trace,
|
|
1354
|
+
// Cap extra payload — drop entirely if serialized size exceeds 32KB
|
|
1355
|
+
extra: (() => {
|
|
1356
|
+
if (!event.extra) return event.extra;
|
|
1357
|
+
try {
|
|
1358
|
+
return JSON.stringify(event.extra).length > 32768 ? {} : event.extra;
|
|
1359
|
+
} catch {
|
|
1360
|
+
return {};
|
|
1361
|
+
}
|
|
1362
|
+
})()
|
|
1363
|
+
};
|
|
1364
|
+
const next = [...buffer, sanitized];
|
|
1349
1365
|
set({ buffer: next });
|
|
1350
1366
|
if (next.length >= maxSize || event.level === "error") {
|
|
1351
1367
|
get().flush();
|
|
@@ -1364,15 +1380,48 @@ var monitorStore = createStore((set, get) => ({
|
|
|
1364
1380
|
}));
|
|
1365
1381
|
|
|
1366
1382
|
// src/client/capture/js-errors.ts
|
|
1383
|
+
var MSG_MAX = 2e3;
|
|
1384
|
+
function truncate(s, max = MSG_MAX) {
|
|
1385
|
+
return s.length > max ? s.slice(0, max - 1) + "\u2026" : s;
|
|
1386
|
+
}
|
|
1387
|
+
__name(truncate, "truncate");
|
|
1388
|
+
var HYDRATION_NOISE = [
|
|
1389
|
+
/hydration failed/i,
|
|
1390
|
+
/there was an error while hydrating/i,
|
|
1391
|
+
/minified react error #418/i,
|
|
1392
|
+
/minified react error #423/i,
|
|
1393
|
+
/minified react error #425/i,
|
|
1394
|
+
/text content does not match server-rendered html/i
|
|
1395
|
+
];
|
|
1396
|
+
function isHydrationNoise(msg) {
|
|
1397
|
+
return HYDRATION_NOISE.some((p) => p.test(msg));
|
|
1398
|
+
}
|
|
1399
|
+
__name(isHydrationNoise, "isHydrationNoise");
|
|
1400
|
+
var CLIENT_DEDUP_TTL = 5 * 60 * 1e3;
|
|
1401
|
+
var recentFingerprints = /* @__PURE__ */ new Map();
|
|
1402
|
+
function isRecentlySent(fingerprint) {
|
|
1403
|
+
const now = Date.now();
|
|
1404
|
+
const last = recentFingerprints.get(fingerprint);
|
|
1405
|
+
if (last !== void 0 && now - last < CLIENT_DEDUP_TTL) return true;
|
|
1406
|
+
recentFingerprints.set(fingerprint, now);
|
|
1407
|
+
if (recentFingerprints.size > 100) {
|
|
1408
|
+
const oldest = [...recentFingerprints.entries()].sort((a, b) => a[1] - b[1])[0];
|
|
1409
|
+
recentFingerprints.delete(oldest[0]);
|
|
1410
|
+
}
|
|
1411
|
+
return false;
|
|
1412
|
+
}
|
|
1413
|
+
__name(isRecentlySent, "isRecentlySent");
|
|
1367
1414
|
function installJsErrorCapture() {
|
|
1368
1415
|
if (typeof window === "undefined") return () => {
|
|
1369
1416
|
};
|
|
1370
1417
|
const onError = /* @__PURE__ */ __name(async (message, source, lineno, colno, error) => {
|
|
1371
1418
|
try {
|
|
1372
|
-
const msg = typeof message === "string" ? message : String(message);
|
|
1419
|
+
const msg = truncate(typeof message === "string" ? message : String(message));
|
|
1420
|
+
if (isHydrationNoise(msg)) return;
|
|
1373
1421
|
const stack = error?.stack ?? `at ${source}:${lineno}:${colno}`;
|
|
1374
1422
|
const url = window.location.href;
|
|
1375
1423
|
const fingerprint = await computeFingerprint(msg, stack, url);
|
|
1424
|
+
if (isRecentlySent(fingerprint)) return;
|
|
1376
1425
|
const { config } = monitorStore.getState();
|
|
1377
1426
|
monitorStore.getState().push({
|
|
1378
1427
|
event_type: "JS_ERROR" /* JS_ERROR */,
|
|
@@ -1393,10 +1442,12 @@ function installJsErrorCapture() {
|
|
|
1393
1442
|
const onUnhandledRejection = /* @__PURE__ */ __name(async (e) => {
|
|
1394
1443
|
try {
|
|
1395
1444
|
const reason = e.reason;
|
|
1396
|
-
const msg = reason instanceof Error ? reason.message : typeof reason === "string" ? reason : "Unhandled promise rejection";
|
|
1445
|
+
const msg = truncate(reason instanceof Error ? reason.message : typeof reason === "string" ? reason : "Unhandled promise rejection");
|
|
1446
|
+
if (isHydrationNoise(msg)) return;
|
|
1397
1447
|
const stack = reason instanceof Error ? reason.stack ?? "" : "";
|
|
1398
1448
|
const url = window.location.href;
|
|
1399
1449
|
const fingerprint = await computeFingerprint(msg, stack, url);
|
|
1450
|
+
if (isRecentlySent(fingerprint)) return;
|
|
1400
1451
|
const { config } = monitorStore.getState();
|
|
1401
1452
|
monitorStore.getState().push({
|
|
1402
1453
|
event_type: "JS_ERROR" /* JS_ERROR */,
|
|
@@ -1433,16 +1484,23 @@ var typeMap = {
|
|
|
1433
1484
|
warn: "WARNING" /* WARNING */,
|
|
1434
1485
|
error: "ERROR" /* ERROR */
|
|
1435
1486
|
};
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1487
|
+
var ARG_MAX = 500;
|
|
1488
|
+
function stringifyArg(a) {
|
|
1489
|
+
let s;
|
|
1490
|
+
if (typeof a === "string") s = a;
|
|
1491
|
+
else if (a instanceof Error) s = a.message;
|
|
1492
|
+
else {
|
|
1440
1493
|
try {
|
|
1441
|
-
|
|
1494
|
+
s = JSON.stringify(a);
|
|
1442
1495
|
} catch {
|
|
1443
|
-
|
|
1496
|
+
s = String(a);
|
|
1444
1497
|
}
|
|
1445
|
-
}
|
|
1498
|
+
}
|
|
1499
|
+
return s.length > ARG_MAX ? s.slice(0, ARG_MAX - 1) + "\u2026" : s;
|
|
1500
|
+
}
|
|
1501
|
+
__name(stringifyArg, "stringifyArg");
|
|
1502
|
+
function stringify(args) {
|
|
1503
|
+
return args.map(stringifyArg).join(" ");
|
|
1446
1504
|
}
|
|
1447
1505
|
__name(stringify, "stringify");
|
|
1448
1506
|
async function captureConsoleEvent(level, args) {
|
|
@@ -1510,10 +1568,11 @@ function installValidationCapture() {
|
|
|
1510
1568
|
try {
|
|
1511
1569
|
const detail = event.detail;
|
|
1512
1570
|
const { config } = monitorStore.getState();
|
|
1571
|
+
const rawMsg = `Zod validation error in ${detail.operation}: ${detail.error?.message ?? "unknown"}`;
|
|
1513
1572
|
monitorStore.getState().push({
|
|
1514
1573
|
event_type: "WARNING" /* WARNING */,
|
|
1515
1574
|
level: "warn" /* WARN */,
|
|
1516
|
-
message:
|
|
1575
|
+
message: rawMsg.length > 500 ? rawMsg.slice(0, 499) + "\u2026" : rawMsg,
|
|
1517
1576
|
url: window.location.href,
|
|
1518
1577
|
http_method: detail.method,
|
|
1519
1578
|
http_url: detail.path,
|