Skip to content

Commit bd53ce9

Browse files
committed
Update version to 3.2.9-rc.1 in package.json and refactor consoleCatcher to improve console method interception and prevent infinite loops.
1 parent 93de9e4 commit bd53ce9

File tree

2 files changed

+68
-68
lines changed

2 files changed

+68
-68
lines changed

package.json

Lines changed: 1 addition & 1 deletion
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.9",
4+
"version": "3.2.9-rc.1",
55
"description": "JavaScript errors tracking for Hawk.so",
66
"files": [
77
"dist"

src/addons/consoleCatcher.ts

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

77
/**
88
* Console interceptor that captures and formats console output
@@ -13,6 +13,72 @@ export class ConsoleCatcher {
1313
private isInitialized = false;
1414
private isProcessing = false;
1515

16+
/**
17+
* Initializes the console interceptor by overriding default console methods
18+
*/
19+
public init(): void {
20+
if (this.isInitialized) {
21+
return;
22+
}
23+
24+
this.isInitialized = true;
25+
const consoleMethods: string[] = ['log', 'warn', 'error', 'info', 'debug'];
26+
27+
consoleMethods.forEach((method) => {
28+
if (typeof window.console[method] !== 'function') {
29+
return;
30+
}
31+
32+
const oldFunction = window.console[method].bind(window.console);
33+
34+
window.console[method] = (...args: unknown[]): void => {
35+
// Prevent recursive calls
36+
if (this.isProcessing) {
37+
return oldFunction(...args);
38+
}
39+
40+
/**
41+
* If the console call originates from Vue's internal runtime bundle, skip interception
42+
* to avoid capturing Vue-internal warnings and causing recursive loops.
43+
*/
44+
const rawStack = new Error().stack || '';
45+
if (rawStack.includes('runtime-core.esm-bundler.js')) {
46+
return oldFunction(...args);
47+
}
48+
49+
// Additional protection against Hawk internal calls
50+
if (rawStack.includes('hawk.javascript') || rawStack.includes('@hawk.so')) {
51+
return oldFunction(...args);
52+
}
53+
54+
this.isProcessing = true;
55+
56+
try {
57+
const stack = new Error().stack?.split('\n').slice(2).join('\n') || '';
58+
const { message, styles } = this.formatConsoleArgs(args);
59+
60+
const logEvent: ConsoleLogEvent = {
61+
method,
62+
timestamp: new Date(),
63+
type: method,
64+
message,
65+
stack,
66+
fileLine: stack.split('\n')[0]?.trim(),
67+
styles,
68+
};
69+
70+
this.addToConsoleOutput(logEvent);
71+
} catch (error) {
72+
// Silently ignore errors in console processing to prevent infinite loops
73+
} finally {
74+
this.isProcessing = false;
75+
}
76+
77+
oldFunction(...args);
78+
};
79+
});
80+
}
81+
1682
/**
1783
* Converts any argument to its string representation
1884
*/
@@ -113,72 +179,6 @@ export class ConsoleCatcher {
113179
};
114180
}
115181

116-
/**
117-
* Initializes the console interceptor by overriding default console methods
118-
*/
119-
public init(): void {
120-
if (this.isInitialized) {
121-
return;
122-
}
123-
124-
this.isInitialized = true;
125-
const consoleMethods: string[] = ['log', 'warn', 'error', 'info', 'debug'];
126-
127-
consoleMethods.forEach((method) => {
128-
if (typeof window.console[method] !== 'function') {
129-
return;
130-
}
131-
132-
const oldFunction = window.console[method].bind(window.console);
133-
134-
window.console[method] = (...args: unknown[]): void => {
135-
// Prevent recursive calls
136-
if (this.isProcessing) {
137-
return oldFunction(...args);
138-
}
139-
140-
/**
141-
* If the console call originates from Vue's internal runtime bundle, skip interception
142-
* to avoid capturing Vue-internal warnings and causing recursive loops.
143-
*/
144-
const rawStack = new Error().stack || '';
145-
if (rawStack.includes('runtime-core.esm-bundler.js')) {
146-
return oldFunction(...args);
147-
}
148-
149-
// Additional protection against Hawk internal calls
150-
if (rawStack.includes('hawk.javascript') || rawStack.includes('@hawk.so')) {
151-
return oldFunction(...args);
152-
}
153-
154-
this.isProcessing = true;
155-
156-
try {
157-
const stack = new Error().stack?.split('\n').slice(2).join('\n') || '';
158-
const { message, styles } = this.formatConsoleArgs(args);
159-
160-
const logEvent: ConsoleLogEvent = {
161-
method,
162-
timestamp: new Date(),
163-
type: method,
164-
message,
165-
stack,
166-
fileLine: stack.split('\n')[0]?.trim(),
167-
styles,
168-
};
169-
170-
this.addToConsoleOutput(logEvent);
171-
} catch (error) {
172-
// Silently ignore errors in console processing to prevent infinite loops
173-
} finally {
174-
this.isProcessing = false;
175-
}
176-
177-
oldFunction(...args);
178-
};
179-
});
180-
}
181-
182182
/**
183183
* Handles error events by converting them to console log events
184184
*/

0 commit comments

Comments
 (0)