@fanboynz/network-scanner 1.0.63 → 1.0.65

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.
@@ -11,7 +11,7 @@ const { formatLogMessage, messageColors } = require('./colorize');
11
11
  * @param {number} timeout - Timeout in milliseconds (default: 5000)
12
12
  * @returns {Promise<object>} Health check result
13
13
  */
14
- async function checkBrowserHealth(browserInstance, timeout = 5000) {
14
+ async function checkBrowserHealth(browserInstance, timeout = 8000) {
15
15
  const healthResult = {
16
16
  healthy: false,
17
17
  pageCount: 0,
@@ -44,7 +44,7 @@ async function checkBrowserHealth(browserInstance, timeout = 5000) {
44
44
  healthResult.responseTime = Date.now() - startTime;
45
45
 
46
46
  // Test 3: Check for excessive pages (memory leak indicator)
47
- if (pages.length > 20) {
47
+ if (pages.length > 30) {
48
48
  healthResult.recommendations.push('Too many open pages - consider browser restart');
49
49
  }
50
50
 
@@ -83,7 +83,7 @@ async function checkBrowserHealth(browserInstance, timeout = 5000) {
83
83
  }
84
84
 
85
85
  // Test 5: Check response time performance
86
- if (healthResult.responseTime > 3000) {
86
+ if (healthResult.responseTime > 5000) {
87
87
  healthResult.recommendations.push('Slow browser response - consider restart');
88
88
  }
89
89
 
@@ -95,11 +95,19 @@ async function checkBrowserHealth(browserInstance, timeout = 5000) {
95
95
  healthResult.responseTime = Date.now() - startTime;
96
96
 
97
97
  // Categorize error types for better recommendations
98
- if (error.message.includes('Runtime.callFunctionOn timed out') ||
99
- error.message.includes('Protocol error') ||
100
- error.message.includes('Target closed')) {
98
+ // Enhanced error categorization for Puppeteer 23.x
99
+ if (isCriticalProtocolError(error)) {
101
100
  healthResult.recommendations.push('Browser restart required - critical protocol error');
102
101
  healthResult.criticalError = true;
102
+ } else if (error.message.includes('WebSocket') ||
103
+ error.message.includes('Connection terminated') ||
104
+ error.message.includes('Network service crashed')) {
105
+ // New error types more common in Puppeteer 23.x
106
+ healthResult.recommendations.push('Browser restart required - connection error');
107
+ healthResult.criticalError = true;
108
+ } else if (error.message.includes('AbortError') ||
109
+ error.message.includes('Operation was aborted')) {
110
+ healthResult.recommendations.push('Browser restart recommended - operation aborted');
103
111
  } else if (error.message.includes('timeout') || error.message.includes('unresponsive')) {
104
112
  healthResult.recommendations.push('Browser restart required - unresponsive');
105
113
  healthResult.criticalError = true;
@@ -176,7 +184,18 @@ function isCriticalProtocolError(error) {
176
184
  'Session closed',
177
185
  'Connection closed',
178
186
  'Browser has been closed',
179
- 'Runtime.evaluate timed out'
187
+ 'Runtime.evaluate timed out',
188
+ // New Puppeteer 23.x critical errors
189
+ 'WebSocket is not open',
190
+ 'WebSocket connection lost',
191
+ 'Connection terminated',
192
+ 'Network service crashed',
193
+ 'Browser disconnected',
194
+ 'CDP session invalid',
195
+ 'Browser process exited',
196
+ 'Navigation timeout of',
197
+ 'Page crashed',
198
+ 'Renderer process crashed'
180
199
  ];
181
200
 
182
201
  return criticalErrors.some(criticalError =>
@@ -184,6 +203,54 @@ function isCriticalProtocolError(error) {
184
203
  );
185
204
  }
186
205
 
206
+ /**
207
+ * Enhanced browser connectivity test for Puppeteer 23.x
208
+ * Tests WebSocket connection and CDP session validity
209
+ */
210
+ async function testBrowserConnectivity(browserInstance, timeout = 2500) {
211
+ const connectivityResult = {
212
+ connected: false,
213
+ cdpResponsive: false,
214
+ websocketHealthy: false,
215
+ error: null
216
+ };
217
+
218
+ try {
219
+ // Test 1: Basic browser connection
220
+ const isConnected = browserInstance.isConnected();
221
+ connectivityResult.connected = isConnected;
222
+
223
+ if (!isConnected) {
224
+ connectivityResult.error = 'Browser is not connected';
225
+ return connectivityResult;
226
+ }
227
+
228
+ // Test 2: CDP responsiveness with version check
229
+ try {
230
+ const version = await Promise.race([
231
+ browserInstance.version(),
232
+ new Promise((_, reject) =>
233
+ setTimeout(() => reject(new Error('CDP version check timeout')), timeout)
234
+ )
235
+ ]);
236
+
237
+ connectivityResult.cdpResponsive = true;
238
+ connectivityResult.websocketHealthy = true; // If version works, WebSocket is healthy
239
+
240
+ } catch (cdpError) {
241
+ connectivityResult.error = `CDP not responsive: ${cdpError.message}`;
242
+ if (cdpError.message.includes('WebSocket')) {
243
+ connectivityResult.websocketHealthy = false;
244
+ }
245
+ }
246
+
247
+ } catch (error) {
248
+ connectivityResult.error = error.message;
249
+ }
250
+
251
+ return connectivityResult;
252
+ }
253
+
187
254
  /**
188
255
  * Performs comprehensive browser health assessment
189
256
  * @param {import('puppeteer').Browser} browserInstance - Puppeteer browser instance
@@ -192,8 +259,9 @@ function isCriticalProtocolError(error) {
192
259
  */
193
260
  async function performHealthAssessment(browserInstance, options = {}) {
194
261
  const {
195
- timeout = 5000,
262
+ timeout = 8000,
196
263
  checkMemory = true,
264
+ testConnectivity = true,
197
265
  forceDebug = false
198
266
  } = options;
199
267
 
@@ -202,6 +270,7 @@ async function performHealthAssessment(browserInstance, options = {}) {
202
270
  timestamp: new Date().toISOString(),
203
271
  browser: {},
204
272
  memory: {},
273
+ connectivity: {},
205
274
  recommendations: [],
206
275
  needsRestart: false
207
276
  };
@@ -213,6 +282,11 @@ async function performHealthAssessment(browserInstance, options = {}) {
213
282
  // Browser responsiveness check
214
283
  assessment.browser = await checkBrowserHealth(browserInstance, timeout);
215
284
 
285
+ // Enhanced connectivity check for Puppeteer 23.x
286
+ if (testConnectivity) {
287
+ assessment.connectivity = await testBrowserConnectivity(browserInstance, timeout);
288
+ }
289
+
216
290
  // Memory usage check (if enabled and available)
217
291
  if (checkMemory) {
218
292
  assessment.memory = await checkBrowserMemory(browserInstance);
@@ -221,6 +295,7 @@ async function performHealthAssessment(browserInstance, options = {}) {
221
295
  // Combine recommendations
222
296
  assessment.recommendations = [
223
297
  ...assessment.browser.recommendations,
298
+ ...(assessment.connectivity.error ? [`Connectivity issue: ${assessment.connectivity.error}`] : []),
224
299
  ...(assessment.memory.recommendations || [])
225
300
  ];
226
301
 
@@ -231,6 +306,9 @@ async function performHealthAssessment(browserInstance, options = {}) {
231
306
  } else if (assessment.browser.criticalError) {
232
307
  assessment.overall = 'critical';
233
308
  assessment.needsRestart = true;
309
+ } else if (testConnectivity && (!assessment.connectivity.connected || !assessment.connectivity.cdpResponsive)) {
310
+ assessment.overall = 'disconnected';
311
+ assessment.needsRestart = true;
234
312
  } else if (assessment.recommendations.length > 0) {
235
313
  assessment.overall = 'degraded';
236
314
  assessment.needsRestart = assessment.recommendations.some(rec =>
@@ -279,8 +357,9 @@ async function monitorBrowserHealth(browserInstance, context = {}, options = {})
279
357
  try {
280
358
  // Perform health assessment
281
359
  const assessment = await performHealthAssessment(browserInstance, {
282
- timeout: 5000,
360
+ timeout: 8000,
283
361
  checkMemory: true,
362
+ testConnectivity: true, // Enable enhanced connectivity testing
284
363
  forceDebug
285
364
  });
286
365
 
@@ -290,15 +369,22 @@ async function monitorBrowserHealth(browserInstance, context = {}, options = {})
290
369
  if (assessment.browser.criticalError) {
291
370
  result.shouldRestart = true;
292
371
  result.reason = `Critical protocol error detected - immediate restart required`;
372
+ } else if (assessment.connectivity && (!assessment.connectivity.connected || !assessment.connectivity.cdpResponsive)) {
373
+ result.shouldRestart = true;
374
+ result.reason = `Browser connectivity lost - WebSocket/CDP failure`;
293
375
  } else if (assessment.needsRestart) {
294
376
  result.shouldRestart = true;
295
377
  result.reason = `Browser health: ${assessment.overall} - ${assessment.recommendations[0] || 'restart needed'}`;
296
378
  } else if (urlsSinceCleanup >= cleanupInterval) {
297
379
  result.shouldRestart = true;
298
380
  result.reason = `Scheduled cleanup after ${urlsSinceCleanup} URLs`;
299
- } else if (assessment.browser.responseTime > 4000) {
381
+ } else if (assessment.browser.responseTime > 6000) {
382
+ result.shouldRestart = true;
383
+ result.reason = `Slow browser response: ${assessment.browser.responseTime}ms (threshold: 6000ms)`;
384
+ } else if (assessment.browser.pageCount > 40) {
385
+ // More aggressive page count monitoring for Puppeteer 23.x
300
386
  result.shouldRestart = true;
301
- result.reason = `Slow browser response: ${assessment.browser.responseTime}ms`;
387
+ result.reason = `Too many open pages: ${assessment.browser.pageCount} (memory leak protection)`;
302
388
  }
303
389
 
304
390
  // Logging
@@ -308,7 +394,9 @@ async function monitorBrowserHealth(browserInstance, context = {}, options = {})
308
394
  }
309
395
 
310
396
  if (forceDebug && !result.shouldRestart) {
311
- console.log(formatLogMessage('debug', `Browser health OK - continuing (pages: ${assessment.browser.pageCount}, response: ${assessment.browser.responseTime}ms)`));
397
+ const connectivity = assessment.connectivity.connected ? 'connected' : 'disconnected';
398
+ const cdp = assessment.connectivity.cdpResponsive ? 'responsive' : 'unresponsive';
399
+ console.log(formatLogMessage('debug', `Browser health OK - continuing (pages: ${assessment.browser.pageCount}, response: ${assessment.browser.responseTime}ms, ${connectivity}, CDP: ${cdp})`));
312
400
  }
313
401
 
314
402
  } catch (monitorError) {
@@ -330,8 +418,9 @@ async function monitorBrowserHealth(browserInstance, context = {}, options = {})
330
418
  */
331
419
  async function isBrowserHealthy(browserInstance) {
332
420
  try {
333
- const health = await checkBrowserHealth(browserInstance, 3000);
334
- return health.healthy;
421
+ const health = await checkBrowserHealth(browserInstance, 5000); // Faster timeout
422
+ const connectivity = await testBrowserConnectivity(browserInstance, 3000);
423
+ return health.healthy && connectivity.connected && connectivity.cdpResponsive;
335
424
  } catch (error) {
336
425
  return false;
337
426
  }
@@ -340,6 +429,7 @@ async function isBrowserHealthy(browserInstance) {
340
429
  module.exports = {
341
430
  checkBrowserHealth,
342
431
  checkBrowserMemory,
432
+ testBrowserConnectivity,
343
433
  performHealthAssessment,
344
434
  monitorBrowserHealth,
345
435
  isBrowserHealthy,
package/lib/cdp.js CHANGED
@@ -87,8 +87,9 @@ async function createCDPSession(page, currentUrl, options = {}) {
87
87
  let cdpSession = null;
88
88
 
89
89
  try {
90
- // Create CDP session - this connects to Chrome's internal debugging interface
91
- cdpSession = await page.target().createCDPSession();
90
+ // Create CDP session using modern Puppeteer 20+ API
91
+ // page.target().createCDPSession() was deprecated in 19+ and removed in 20+
92
+ cdpSession = await page.createCDPSession();
92
93
 
93
94
  // Enable network domain - required for network event monitoring
94
95
  await cdpSession.send('Network.enable');
@@ -140,8 +141,12 @@ async function createCDPSession(page, currentUrl, options = {}) {
140
141
  cdpSession = null; // Reset on failure
141
142
 
142
143
  // Categorize CDP errors for proper handling
144
+ // Enhanced error handling for Puppeteer 20+ error patterns
143
145
  if (cdpErr.message.includes('Network.enable timed out') ||
144
- cdpErr.message.includes('Protocol error')) {
146
+ cdpErr.message.includes('Protocol error') ||
147
+ cdpErr.message.includes('Session closed') ||
148
+ cdpErr.message.includes('Target closed') ||
149
+ cdpErr.message.includes('Browser has been closed')) {
145
150
  // CRITICAL ERROR: Browser is broken and needs restart
146
151
  // Re-throw these errors so calling code can handle browser restart
147
152
  throw new Error(`Browser protocol broken: ${cdpErr.message}`);