Some checks failed
Deploy to Test Environment / deploy-to-test (push) Failing after 58s
58 lines
2.3 KiB
TypeScript
58 lines
2.3 KiB
TypeScript
// src/services/systemService.ts
|
|
import { exec as nodeExec } from 'child_process';
|
|
import { promisify } from 'util';
|
|
import { logger } from './logger.server';
|
|
|
|
// Define a type for the exec function for better type safety and testability.
|
|
// It matches the signature of a promisified child_process.exec.
|
|
export type ExecAsync = (command: string) => Promise<{ stdout: string; stderr: string }>;
|
|
|
|
export class SystemService {
|
|
private execAsync: ExecAsync;
|
|
|
|
constructor(execAsync: ExecAsync) {
|
|
this.execAsync = execAsync;
|
|
}
|
|
|
|
async getPm2Status(): Promise<{ success: boolean; message: string }> {
|
|
try {
|
|
const { stdout, stderr } = await this.execAsync('pm2 describe flyer-crawler-api');
|
|
|
|
// If the command runs but produces output on stderr, treat it as an error.
|
|
// This handles cases where pm2 might issue warnings but still exit 0.
|
|
if (stderr) {
|
|
throw new Error(`PM2 command produced an error: ${stderr}`);
|
|
}
|
|
|
|
const isOnline = /│\s*status\s*│\s*online\s*│/m.test(stdout);
|
|
const message = isOnline
|
|
? 'Application is online and running under PM2.'
|
|
: 'Application process exists but is not online.';
|
|
return { success: isOnline, message };
|
|
} catch (error: unknown) {
|
|
// If the command fails (non-zero exit code), check if it's because the process doesn't exist.
|
|
// This is a normal "not found" case, not a system error.
|
|
// The error message can be in stdout or stderr depending on the pm2 version.
|
|
const execError = error as { stdout?: string; stderr?: string; message?: string };
|
|
const output = execError.stdout || execError.stderr || '';
|
|
if (output.includes("doesn't exist")) {
|
|
logger.warn('[SystemService] PM2 process "flyer-crawler-api" not found.');
|
|
return {
|
|
success: false,
|
|
message: 'Application process is not running under PM2.',
|
|
};
|
|
}
|
|
// For any other error, log it and re-throw to be handled as a 500.
|
|
logger.error(
|
|
{ error: execError.stderr || execError.message },
|
|
'[SystemService] Error executing pm2 describe:',
|
|
);
|
|
throw error;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Instantiate the service with the real dependency for the application
|
|
const realExecAsync = promisify(nodeExec);
|
|
export const systemService = new SystemService(realExecAsync);
|