{"record":{"id":"30ee944a1e107b4a","repo":"docmirror/dev-sidecar","slug":"server-process-exit-code-code-signal","errorCode":null,"errorMessage":"server process exit, code: ${code}, signal:","messagePattern":"server process exit, code: (.+?), signal:","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/core/src/modules/server/index.js","lineNumber":122,"sourceCode":"      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\n        }\n        fireStatus(false) // 启动失败\n        event.fire('error', { key: 'server', value: code, error: msg.event, message: msg.message })\n      } else if (msg.type === 'speed') {\n        event.fire('speed', msg.event)\n      }","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/docmirror/dev-sidecar/blob/7710cd56cce760c708f30b01d2d4056eb8c402d5/packages/core/src/modules/server/index.js#L104-L140","documentation":"A warning log from the `exit` handler on the forked mitmproxy child process (packages/core/src/modules/server/index.js:121-123). It reports that the child process has terminated, including the exit code (or null) and, when terminated by a signal, the signal name. This is the definitive lifecycle event telling the parent the proxy server is no longer running.","triggerScenarios":"Calling server.close()/kill() (SIGINT, line 146); the child crashes (non-zero exit code or signal like SIGSEGV/SIGKILL); the child calls process.exit after an uncaughtException; the OS kills the process (OOM killer).","commonSituations":"Intentional shutdown shows code 0 / SIGINT; crash loops show repeated non-zero codes — often port already in use (EADDRINUSE), invalid running.json, or missing native module in the child; OOM kills show signal SIGKILL under memory pressure.","solutions":["If exit code is 0 or signal is SIGINT and you called close/kill/restart, this is expected — ignore.","For unexpected exits, read `~/.dev-sidecar/logs/server.log` and core.log for the error printed just before exit (EADDRINUSE, config parse failure, uncaughtException).","If killed by SIGKILL, check system memory/OOM killer logs (dmesg) and reduce child memory usage.","Add restart logic: on non-zero exit without a pending shutdown, call serverApi.restart({ mitmproxyPath }) to restore the proxy.","Confirm the mitmproxyPath points to the correct entry of the installed @docmirror/mitmproxy version."],"exampleFix":"// before\nserverProcess.on('exit', (code, signal) => {\n  log.warn(`server process exit, code: ${code}, signal:`, signal)\n})\n// after\nserverProcess.on('exit', (code, signal) => {\n  log.warn(`server process exit, code: ${code}, signal:`, signal)\n  if (code !== 0 && !shuttingDown) {\n    log.error('server crashed unexpectedly, restarting')\n    setTimeout(() => serverApi.restart({ mitmproxyPath }), 2000)\n  }\n})","handlingStrategy":"fallback","validationCode":"// avoid broken stdout pipes in headless/daemon environments\nif (!process.stdout.isTTY && process.env.DAEMON_MODE) {\n  process.env.DEV_SIDECAR_LOG_TO_CONSOLE = 'false' // file-only logging, no stdout pipe to break\n}","typeGuard":null,"tryCatchPattern":"try {\n  serverProcess.write(streamData)\n} catch (e) {\n  if (e.code === 'EPIPE') {\n    log.warn('child pipe closed; falling back to file logging')\n    switchToFileLogging()\n  }\n}","preventionTips":["Shut down the child (server.close()) before the parent exits so IPC/stdout pipes close cleanly.","Run daemons with DEV_SIDECAR_LOG_TO_CONSOLE=false so logs go to files, not fragile terminal pipes.","Don't kill the GUI/CLI parent with SIGKILL; use graceful shutdown to avoid orphaned children with dead pipes.","Attach error handlers on child stdout/stderr streams to absorb EPIPE instead of crashing."],"tags":["logging","child-process","process-exit","crash"],"backgroundTag":"child-process-unexpected-exit","analyzedSha":"7710cd56cce760c708f30b01d2d4056eb8c402d5","analyzedAt":"2026-08-31T22:07:07.234Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}