fix(nodecg): include actionable diagnostics when process exits before readiness (#27)

This commit is contained in:
Pandipipas
2026-02-23 22:24:22 +01:00
committed by GitHub
parent 1f7b05e703
commit 4aa75802cc
2 changed files with 64 additions and 2 deletions
+21 -2
View File
@@ -49,6 +49,8 @@ export function createNodecgProcessManager({
let nodecgProcess: ChildProcess | null = null;
let stopNodecgPromise: Promise<void> | null = null;
let lastExit: { code: number | null; signal: NodeJS.Signals | null } | null = null;
let lastStderrLine: string | null = null;
const startNodecgProcess = async (): Promise<ChildProcess> => {
validateNodecgInstall(
@@ -85,16 +87,21 @@ export function createNodecgProcessManager({
});
child.stderr?.on("data", (chunk) => {
resolvedDeps.stderrWrite(String(chunk));
const line = String(chunk);
lastStderrLine = line.trim().length > 0 ? line.trim() : lastStderrLine;
resolvedDeps.stderrWrite(line);
});
log(`NodeCG started with pid=${child.pid} using ${NODE_RUNTIME_NAME}`);
child.on("exit", (code, signal) => {
log(`NodeCG exited code=${code} signal=${signal ?? "none"}`);
lastExit = { code, signal };
nodecgProcess = null;
});
lastExit = null;
lastStderrLine = null;
nodecgProcess = child;
return child;
};
@@ -102,7 +109,19 @@ export function createNodecgProcessManager({
const waitForNodecgReady = async (startTime: number): Promise<void> => {
while (Date.now() - startTime < appConfig.startupTimeoutMs) {
if (!nodecgProcess) {
throw new Error("NodeCG terminó antes de estar listo.");
const exitDetails = lastExit
? `Última salida registrada: code=${lastExit.code ?? "null"}, signal=${lastExit.signal ?? "none"}.`
: "No se registró código de salida del proceso NodeCG.";
const stderrDetails = lastStderrLine ? `Último stderr: ${lastStderrLine}` : "Sin salida stderr capturada.";
throw new Error(
[
"NodeCG terminó antes de estar listo.",
exitDetails,
stderrDetails,
`Ruta NodeCG: ${nodecgRootPath}`,
"Revisa que lib/nodecg tenga dependencias instaladas y que el bundle exista.",
].join("\n"),
);
}
try {