Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check exit code #209

Open
fpoli opened this issue Jan 27, 2023 · 0 comments
Open

Check exit code #209

fpoli opened this issue Jan 27, 2023 · 0 comments
Labels
enhancement New feature or request good-first-issue Good for newcomers

Comments

@fpoli
Copy link
Member

fpoli commented Jan 27, 2023

The Viper IDE took its spawn function from this repository. In the process, they did some nice changes, among with a check of the exist code of the spawned process: viperproject/viper-ide#357. We should port the same check to this repository.

Relevant code:

export function spawn(
cmd: string,
args?: string[] | undefined,
{ options, onStdout, onStderr }: {
options?: childProcess.SpawnOptionsWithoutStdio;
onStdout?: ((data: string) => void);
onStderr?: ((data: string) => void);
} = {},
destructors?: Set<KillFunction>,
): Promise<Output> {
const description = `${cmd} ${args?.join(" ") ?? ""}`;
log(`Run command '${description}'`);
let stdout = "";
let stderr = "";
const start = process.hrtime();
const proc = childProcess.spawn(cmd, args, options);
const status: { killed: boolean } = { killed: false };
log(`Spawned PID: ${proc.pid}`);
// Register destructor
function killProc() {
if (!status.killed) {
status.killed = true;
// TODO: Try with SIGTERM before.
treeKill(proc.pid, "SIGKILL", (err) => {
if (err) {
log(`Failed to kill process tree of ${proc.pid}: ${err}`);
const succeeded = proc.kill("SIGKILL");
if (!succeeded) {
log(`Failed to kill process ${proc}.`);
}
} else {
log(`Process ${proc.pid} has been killed successfully.`);
}
});
} else {
log(`Process ${proc.pid} has already been killed.`);
}
}
if (destructors) {
destructors.add(killProc);
}
proc.stdout.on("data", (data) => {
stdout += data;
try {
onStdout?.(data);
} catch (e) {
log(`error in stdout handler for '${description}': ${e}`);
}
});
proc.stderr.on("data", (data) => {
stderr += data;
try {
onStderr?.(data);
} catch (e) {
log(`error in stderr handler for '${description}': ${e}`);
}
});
function printOutput(duration: Duration, code: number | null, signal: NodeJS.Signals | null) {
const durationSecMsg = (duration[0] + duration[1] / 1e9).toFixed(1);
log(`Output from '${description}' (${durationSecMsg}s):`);
log("┌──── Begin stdout ────┐");
log(stdout);
log("└──── End stdout ──────┘");
log("┌──── Begin stderr ────┐");
log(stderr);
log("└──── End stderr ──────┘");
log(`Exit code ${code}, signal ${signal}.`);
}
return new Promise((resolve, reject) => {
proc.on("close", (code, signal) => {
const duration = process.hrtime(start);
printOutput(duration, code, signal);
if (destructors) {
destructors.delete(killProc);
}
resolve({ stdout, stderr, code, signal, duration });
});
proc.on("error", (err) => {
const duration = process.hrtime(start);
printOutput(duration, null, null);
log(`Error: ${err}`);
if (destructors) {
destructors.delete(killProc);
}
reject(err);
});
});
}

@fpoli fpoli added enhancement New feature or request good-first-issue Good for newcomers labels Jan 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request good-first-issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

1 participant