{"record":{"id":"22d7fc6f1c85891e","repo":"docmirror/dev-sidecar","slug":"server-process-beforeexit-code","errorCode":null,"errorMessage":"server process beforeExit, code:","messagePattern":"server process beforeExit, code:","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/core/src/modules/server/index.js","lineNumber":116,"sourceCode":"        serverConfig.app.instance = existingInstance\n      }\n      fs.writeFileSync(runningConfigPath, jsonApi.stringify(serverConfig))\n      log.info('保存 running.json 运行时配置文件成功:', runningConfigPath)\n    } catch (e) {\n      log.error('保存 running.json 运行时配置文件失败:', runningConfigPath, ', error:', e)\n      throw e\n    }\n    const serverProcess = fork(mitmproxyPath, [runningConfigPath])\n    server = {\n      id: serverProcess.pid,\n      process: serverProcess,\n      port: serverConfig.port,\n      close () {\n        serverProcess.send({ type: 'action', event: { key: 'close' } })\n      },\n    }\n    serverProcess.on('beforeExit', (code) => {\n      log.warn('server process beforeExit, code:', code)\n    })\n    serverProcess.on('SIGPIPE', (code, signal) => {\n      log.warn(`server process SIGPIPE, code: ${code}, signal:`, signal)\n    })\n    serverProcess.on('exit', (code, signal) => {\n      log.warn(`server process exit, code: ${code}, signal:`, signal)\n    })\n    serverProcess.on('uncaughtException', (err, origin) => {\n      log.error('server process uncaughtException:', err)\n    })\n    serverProcess.on('message', (msg) => {\n      log.debug('收到子进程消息:', JSON.stringify(msg))\n      if (msg.type === 'status') {\n        fireStatus(msg.event)\n      } else if (msg.type === 'error') {\n        let code = ''\n        if (msg.event.code) {\n          code = msg.event.code","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/docmirror/dev-sidecar/blob/7710cd56cce760c708f30b01d2d4056eb8c402d5/packages/core/src/modules/server/index.js#L98-L134","documentation":"A warning log from the `beforeExit` handler attached to the forked mitmproxy child process (packages/core/src/modules/server/index.js:115-117). Node emits `beforeExit` on a child when its event loop drains and it is about to exit normally. In practice for this forked server it signals the child finished its work/loop and is shutting down on its own, code 0 usually meaning normal exit.","triggerScenarios":"The mitmproxy child process's event loop empties (no active handles) so Node begins a normal exit; the child's close action completes; child code calls process.exit after loop drain.","commonSituations":"Server stopped via close() and the child drained cleanly; a bug in the child removes all keep-alive handles (e.g. server closed unexpectedly), making the proxy silently stop while the parent only logs a warning.","solutions":["If you intentionally stopped the server, this is expected — ignore it.","If the server died unexpectedly, check `~/.dev-sidecar/logs/server.log` and core.log for the real cause (port conflict, config parse error, uncaughtException above it).","If the child exits on its own when idle, look for child-side code closing the HTTP/HTTPS listeners; restart via DevSidecar.api.restart() to recover.","Verify running.json config is valid; invalid config can make the child exit right after boot."],"exampleFix":"// before\nserverProcess.on('beforeExit', (code) => {\n  log.warn('server process beforeExit, code:', code)\n})\n// after\nserverProcess.on('beforeExit', (code) => {\n  log.warn('server process beforeExit, code:', code)\n  if (code === 0 && autoRestartEnabled) {\n    log.info('child exited normally but unexpectedly; restarting server')\n    serverApi.restart({ mitmproxyPath })\n  }\n})","handlingStrategy":"validation","validationCode":"const server = DevSidecar.api.server.getServer()\nconst alive = server && server.process && !server.process.killed && server.process.exitCode == null\nif (alive) {\n  console.log('server already running on port', server.port, '- skip startup')\n} else {\n  await DevSidecar.api.startup()\n}","typeGuard":"function isServerAlive (server) {\n  return Boolean(server && server.process && server.process.killed === false && server.process.exitCode == null)\n}","tryCatchPattern":null,"preventionTips":["Gate startup behind an alive-check using getServer() before calling startup().","Use a single-instance lock (Electron requestSingleInstanceLock) so only one path calls startup().","Treat the skip-start return value ({ port }) as success; do not retry startup in a loop on this warning.","Call shutdown() during app quit handlers so stale child processes do not linger."],"tags":["logging","child-process","process-lifecycle","before-exit"],"backgroundTag":"child-process-unexpected-exit","analyzedSha":"7710cd56cce760c708f30b01d2d4056eb8c402d5","analyzedAt":"2026-08-31T22:07:07.234Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}