fix(core): Improve error handling, logging, and test suite; update dependency versions

This commit is contained in:
2025-03-10 23:38:21 +00:00
parent 5c4836fd68
commit 779593f73a
12 changed files with 1648 additions and 236 deletions

View File

@@ -1,5 +1,6 @@
import * as plugins from './plugins.js';
import { EventEmitter } from 'events';
import { Logger, ProcessError, handleError } from './utils.errorhandler.js';
export interface IProcessWrapperOptions {
command: string;
@@ -22,11 +23,13 @@ export class ProcessWrapper extends EventEmitter {
private logs: IProcessLog[] = [];
private logBufferSize: number;
private startTime: Date | null = null;
private logger: Logger;
constructor(options: IProcessWrapperOptions) {
super();
this.options = options;
this.logBufferSize = options.logBuffer || 100;
this.logger = new Logger(`ProcessWrapper:${options.name}`);
}
/**
@@ -36,6 +39,8 @@ export class ProcessWrapper extends EventEmitter {
this.addSystemLog('Starting process...');
try {
this.logger.debug(`Starting process: ${this.options.command}`);
if (this.options.args && this.options.args.length > 0) {
this.process = plugins.childProcess.spawn(this.options.command, this.options.args, {
cwd: this.options.cwd,
@@ -56,14 +61,22 @@ export class ProcessWrapper extends EventEmitter {
// Handle process exit
this.process.on('exit', (code, signal) => {
this.addSystemLog(`Process exited with code ${code}, signal ${signal}`);
const exitMessage = `Process exited with code ${code}, signal ${signal}`;
this.logger.info(exitMessage);
this.addSystemLog(exitMessage);
this.emit('exit', code, signal);
});
// Handle errors
this.process.on('error', (error) => {
this.addSystemLog(`Process error: ${error.message}`);
this.emit('error', error);
const processError = new ProcessError(
error.message,
'ERR_PROCESS_EXECUTION',
{ command: this.options.command, pid: this.process?.pid }
);
this.logger.error(processError);
this.addSystemLog(`Process error: ${processError.toString()}`);
this.emit('error', processError);
});
// Capture stdout
@@ -91,12 +104,22 @@ export class ProcessWrapper extends EventEmitter {
}
this.addSystemLog(`Process started with PID ${this.process.pid}`);
this.logger.info(`Process started with PID ${this.process.pid}`);
this.emit('start', this.process.pid);
} catch (error) {
this.addSystemLog(`Failed to start process: ${error.message}`);
this.emit('error', error);
throw error;
} catch (error: Error | unknown) {
const processError = error instanceof ProcessError
? error
: new ProcessError(
error instanceof Error ? error.message : String(error),
'ERR_PROCESS_START_FAILED',
{ command: this.options.command }
);
this.logger.error(processError);
this.addSystemLog(`Failed to start process: ${processError.toString()}`);
this.emit('error', processError);
throw processError;
}
}
@@ -105,30 +128,43 @@ export class ProcessWrapper extends EventEmitter {
*/
public stop(): void {
if (!this.process) {
this.logger.debug('Stop called but no process is running');
this.addSystemLog('No process running');
return;
}
this.logger.info('Stopping process...');
this.addSystemLog('Stopping process...');
// First try SIGTERM for graceful shutdown
if (this.process.pid) {
try {
this.logger.debug(`Sending SIGTERM to process ${this.process.pid}`);
process.kill(this.process.pid, 'SIGTERM');
// Give it 5 seconds to shut down gracefully
setTimeout(() => {
setTimeout((): void => {
if (this.process && this.process.pid) {
this.logger.warn(`Process ${this.process.pid} did not exit gracefully, force killing...`);
this.addSystemLog('Process did not exit gracefully, force killing...');
try {
process.kill(this.process.pid, 'SIGKILL');
} catch (error) {
} catch (error: Error | unknown) {
// Process might have exited between checks
this.logger.debug(`Failed to send SIGKILL, process probably already exited: ${
error instanceof Error ? error.message : String(error)
}`);
}
}
}, 5000);
} catch (error) {
this.addSystemLog(`Error stopping process: ${error.message}`);
} catch (error: Error | unknown) {
const processError = new ProcessError(
error instanceof Error ? error.message : String(error),
'ERR_PROCESS_STOP_FAILED',
{ pid: this.process.pid }
);
this.logger.error(processError);
this.addSystemLog(`Error stopping process: ${processError.toString()}`);
}
}
}