Skip to content

Commit 5ba0baa

Browse files
authored
Merge pull request #131 from codex-team/fix-infinity-loop
fix(console-tracker): resolve infinity loop issue
2 parents 680a1d8 + 8d54311 commit 5ba0baa

File tree

4 files changed

+36
-23
lines changed

4 files changed

+36
-23
lines changed

package.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@hawk.so/javascript",
33
"type": "commonjs",
4-
"version": "3.2.8",
4+
"version": "3.2.9",
55
"description": "JavaScript errors tracking for Hawk.so",
66
"files": [
77
"dist"
@@ -47,9 +47,8 @@
4747
"vue": "^2"
4848
},
4949
"dependencies": {
50-
"@hawk.so/types": "^0.1.20",
50+
"@hawk.so/types": "^0.1.35",
5151
"error-stack-parser": "^2.1.4",
52-
"safe-stringify": "^1.1.1",
5352
"vite-plugin-dts": "^4.2.4"
5453
}
5554
}

src/addons/consoleCatcher.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
/**
22
* @file Module for intercepting console logs with stack trace capture
33
*/
4-
import safeStringify from 'safe-stringify';
54
import type { ConsoleLogEvent } from '@hawk.so/types';
5+
import Sanitizer from '../modules/sanitizer';
66

77
/**
88
* Creates a console interceptor that captures and formats console output
@@ -31,7 +31,13 @@ function createConsoleCatcher(): {
3131
return String(arg);
3232
}
3333

34-
return safeStringify(arg);
34+
/**
35+
* Sanitize the argument before stringifying to handle circular references, deep objects, etc
36+
* And then it can be stringified safely
37+
*/
38+
const sanitized = Sanitizer.sanitize(arg);
39+
40+
return JSON.stringify(sanitized);
3541
}
3642

3743
/**

src/modules/sanitizer.ts

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,24 @@ export default class Sanitizer {
3333
*
3434
* @param data - any object to sanitize
3535
* @param depth - current depth of recursion
36+
* @param seen - Set of already seen objects to prevent circular references
3637
*/
37-
public static sanitize(data: any, depth = 0): any {
38+
public static sanitize(data: any, depth = 0, seen = new WeakSet<object>()): any {
39+
/**
40+
* Check for circular references on objects and arrays
41+
*/
42+
if (data !== null && typeof data === 'object') {
43+
if (seen.has(data)) {
44+
return '<circular>';
45+
}
46+
seen.add(data);
47+
}
48+
3849
/**
3950
* If value is an Array, apply sanitizing for each element
4051
*/
4152
if (Sanitizer.isArray(data)) {
42-
return this.sanitizeArray(data, depth + 1);
53+
return this.sanitizeArray(data, depth + 1, seen);
4354

4455
/**
4556
* If value is an Element, format it as string with outer HTML
@@ -66,7 +77,7 @@ export default class Sanitizer {
6677
* If values is an object, do recursive call
6778
*/
6879
} else if (Sanitizer.isObject(data)) {
69-
return Sanitizer.sanitizeObject(data, depth + 1);
80+
return Sanitizer.sanitizeObject(data, depth + 1, seen);
7081

7182
/**
7283
* If values is a string, trim it for max-length
@@ -86,8 +97,9 @@ export default class Sanitizer {
8697
*
8798
* @param arr - array to sanitize
8899
* @param depth - current depth of recursion
100+
* @param seen - Set of already seen objects to prevent circular references
89101
*/
90-
private static sanitizeArray(arr: any[], depth: number): any[] {
102+
private static sanitizeArray(arr: any[], depth: number, seen: WeakSet<object>): any[] {
91103
/**
92104
* If the maximum length is reached, slice array to max length and add a placeholder
93105
*/
@@ -99,7 +111,7 @@ export default class Sanitizer {
99111
}
100112

101113
return arr.map((item: any) => {
102-
return Sanitizer.sanitize(item, depth);
114+
return Sanitizer.sanitize(item, depth, seen);
103115
});
104116
}
105117

@@ -108,8 +120,9 @@ export default class Sanitizer {
108120
*
109121
* @param data - object to beautify
110122
* @param depth - current depth of recursion
123+
* @param seen - Set of already seen objects to prevent circular references
111124
*/
112-
private static sanitizeObject(data: { [key: string]: any }, depth: number): Record<string, any> | '<deep object>' | '<big object>' {
125+
private static sanitizeObject(data: { [key: string]: any }, depth: number, seen: WeakSet<object>): Record<string, any> | '<deep object>' | '<big object>' {
113126
/**
114127
* If the maximum depth is reached, return a placeholder
115128
*/
@@ -128,7 +141,7 @@ export default class Sanitizer {
128141

129142
for (const key in data) {
130143
if (Object.prototype.hasOwnProperty.call(data, key)) {
131-
result[key] = Sanitizer.sanitize(data[key], depth);
144+
result[key] = Sanitizer.sanitize(data[key], depth, seen);
132145
}
133146
}
134147

@@ -268,7 +281,7 @@ export default class Sanitizer {
268281
private static formatClassPrototype(target: any): string {
269282
const className = Sanitizer.getClassNameByPrototype(target);
270283

271-
return `<instance of ${className}>`;
284+
return `<class ${className}>`;
272285
}
273286

274287
/**
@@ -279,6 +292,6 @@ export default class Sanitizer {
279292
private static formatClassInstance(target: any): string {
280293
const className = Sanitizer.getClassNameByInstance(target);
281294

282-
return `<class ${className}>`;
295+
return `<instance of ${className}>`;
283296
}
284297
}

yarn.lock

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -316,10 +316,10 @@
316316
minimatch "^3.0.4"
317317
strip-json-comments "^3.1.1"
318318

319-
"@hawk.so/types@^0.1.20":
320-
version "0.1.20"
321-
resolved "https://registry.yarnpkg.com/@hawk.so/types/-/types-0.1.20.tgz#90f4b3998ef5f025f5b99dae31da264d5bbe3450"
322-
integrity sha512-3a07TekmgqOT9OKeMkqcV73NxzK1dS06pG66VaHO0f5DEEH2+SNfZErqe1v8hkLQIk+GkgZVZLtHqnskjQabuw==
319+
"@hawk.so/types@^0.1.35":
320+
version "0.1.35"
321+
resolved "https://registry.yarnpkg.com/@hawk.so/types/-/types-0.1.35.tgz#6afd416dced1cc3282d721ca5621bf452b27aea1"
322+
integrity sha512-uMTAeu6DlRlk+oputJBjTlrm1GzOkIwlMfGhpdOp3sRWe/YPGD6nMYlb9MZoVN6Yee7RIpYD7It+DPeUPAyIFw==
323323
dependencies:
324324
"@types/mongodb" "^3.5.34"
325325

@@ -2619,11 +2619,6 @@ safe-regex-test@^1.0.3:
26192619
es-errors "^1.3.0"
26202620
is-regex "^1.1.4"
26212621

2622-
safe-stringify@^1.1.1:
2623-
version "1.1.1"
2624-
resolved "https://registry.yarnpkg.com/safe-stringify/-/safe-stringify-1.1.1.tgz#f4240f506d041f58374d6106e2a5850f6b1ce576"
2625-
integrity sha512-YSzQLuwp06fuvJD1h6+vVNFYZoXmDs5UUNPUbTvQK7Ap+L0qD4Vp+sN434C+pdS3prVVlUfQdNeiEIgxox/kUQ==
2626-
26272622
semver@^6.3.1:
26282623
version "6.3.1"
26292624
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4"

0 commit comments

Comments
 (0)