codeceptjs 4.0.2-beta.4 → 4.0.2-beta.5

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.
@@ -19,6 +19,18 @@ const stderr = ''
19
19
 
20
20
  const { options, tests, testRoot, workerIndex, poolMode } = workerData
21
21
 
22
+ // Global error handlers to prevent worker from hanging
23
+ process.on('uncaughtException', (err) => {
24
+ console.error(`[Worker ${workerIndex}] Uncaught exception:`, err.message)
25
+ console.error(err.stack)
26
+ process.exit(1)
27
+ })
28
+
29
+ process.on('unhandledRejection', (reason, promise) => {
30
+ console.error(`[Worker ${workerIndex}] Unhandled rejection:`, reason)
31
+ process.exit(1)
32
+ })
33
+
22
34
  // hide worker output
23
35
  // In pool mode, only suppress output if debug is NOT enabled
24
36
  // In regular mode, hide result output but allow step output in verbose/debug
@@ -144,6 +156,7 @@ async function runTests() {
144
156
  try {
145
157
  await codecept.bootstrap()
146
158
  } catch (err) {
159
+ console.error(`[Worker ${workerIndex}] Bootstrap error:`, err.message)
147
160
  throw new Error(`Error while running bootstrap file :${err}`)
148
161
  }
149
162
  listenToParentThread()
@@ -151,8 +164,15 @@ async function runTests() {
151
164
  disablePause()
152
165
  try {
153
166
  await codecept.run()
167
+ } catch (err) {
168
+ console.error(`[Worker ${workerIndex}] Runtime error:`, err.message)
169
+ throw err
154
170
  } finally {
155
- await codecept.teardown()
171
+ try {
172
+ await codecept.teardown()
173
+ } catch (err) {
174
+ console.error(`[Worker ${workerIndex}] Teardown error:`, err.message)
175
+ }
156
176
  }
157
177
  }
158
178
 
package/lib/workers.js CHANGED
@@ -542,8 +542,22 @@ class Workers extends EventEmitter {
542
542
  if (this.isPoolMode) {
543
543
  this.activeWorkers.set(worker, { available: true, workerIndex: null })
544
544
  }
545
+
546
+ // Track last activity time to detect hanging workers
547
+ let lastActivity = Date.now()
548
+ const workerTimeout = 300000 // 5 minutes
549
+
550
+ const timeoutChecker = setInterval(() => {
551
+ const elapsed = Date.now() - lastActivity
552
+ if (elapsed > workerTimeout) {
553
+ console.error(`[Main] Worker appears to be hanging (no activity for ${Math.floor(elapsed/1000)}s). Terminating...`)
554
+ clearInterval(timeoutChecker)
555
+ worker.terminate()
556
+ }
557
+ }, 30000) // Check every 30 seconds
545
558
 
546
559
  worker.on('message', message => {
560
+ lastActivity = Date.now() // Update activity timestamp
547
561
  output.process(message.workerIndex)
548
562
 
549
563
  // Handle test requests for pool mode
@@ -660,11 +674,17 @@ class Workers extends EventEmitter {
660
674
  })
661
675
 
662
676
  worker.on('error', err => {
677
+ console.error(`[Main] Worker error:`, err.message || err)
663
678
  this.errors.push(err)
664
679
  })
665
680
 
666
- worker.on('exit', () => {
681
+ worker.on('exit', (code) => {
682
+ clearInterval(timeoutChecker)
667
683
  this.closedWorkers += 1
684
+
685
+ if (code !== 0) {
686
+ console.error(`[Main] Worker exited with code ${code}`)
687
+ }
668
688
 
669
689
  if (this.isPoolMode) {
670
690
  // Pool mode: finish when all workers have exited and no more tests
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeceptjs",
3
- "version": "4.0.2-beta.4",
3
+ "version": "4.0.2-beta.5",
4
4
  "type": "module",
5
5
  "description": "Supercharged End 2 End Testing Framework for NodeJS",
6
6
  "keywords": [