From f47d6bc28c5713350c9d9a454068e310cc020bbf Mon Sep 17 00:00:00 2001 From: 00Fjongl <65314359+00Fjongl@users.noreply.github.com> Date: Thu, 8 Aug 2024 19:18:01 -0500 Subject: [PATCH 1/2] Flesh out error handling for run-commands.mjs; try simplifying GitHub workflow. --- .github/workflows/ci.yml | 2 +- package.json | 1 - run-command.mjs | 42 ++++++++++++++++++++++++++++++++-------- src/server.mjs | 1 + 4 files changed, 36 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f77d727c..e73c697b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,7 +26,7 @@ jobs: run: npm run build - name: Start server - run: npm run start-test-server + run: npm run manual-start - name: Test server response run: npm test diff --git a/package.json b/package.json index 79efac30..72f138c1 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,6 @@ "manual-start": "node run-command.mjs start", "kill": "node run-command.mjs stop kill", "build": "node run-command.mjs build && cd lib/rammerhead && npm install && npm run build", - "start-test-server": "timeout 5 node backend.js; test $? -eq 124 && ( npm run manual-start & ) || exit 1", "proxy-validator": "node proxyServiceValidator.js" }, "keywords": [ diff --git a/run-command.mjs b/run-command.mjs index 6de824f5..6176e6ef 100644 --- a/run-command.mjs +++ b/run-command.mjs @@ -28,7 +28,7 @@ const shutdown = fileURLToPath(new URL("./src/.shutdown", import.meta.url)); // Run each command line argument passed after node run-command.mjs. // Commands are defined in the switch case statement below. -for (let i = 2; i < process.argv.length; i++) +commands: for (let i = 2; i < process.argv.length; i++) switch (process.argv[i]) { // Commmand to boot up the server. Use PM2 to run if production is true in the // config file. @@ -44,7 +44,10 @@ for (let i = 2; i < process.argv.length; i++) // This should run the server as a background process. else if (process.platform === "win32") exec('START /MIN "" node backend.js', (error, stdout) => { - if (error) throw error; + if (error) { + console.error(error); + process.exitCode = 1; + } console.log(stdout); }); // The following approach (and similar approaches) will not work on Windows, @@ -52,8 +55,16 @@ for (let i = 2; i < process.argv.length; i++) else { const server = fork( fileURLToPath(new URL("./backend.js", import.meta.url)), - {detached: true} + { + cwd: process.cwd(), + stdio: ["inherit", "inherit", "pipe", "ipc"], + detached: true + } ); + server.stderr.on("data", stderr => { + console.error(stderr.toString()); + process.exitCode = 1; + }); server.unref(); server.disconnect(); } @@ -63,7 +74,7 @@ for (let i = 2; i < process.argv.length; i++) // to shut down. This is done by sending a GET request to the server. case "stop": { await writeFile(shutdown, ""); - let timeoutId = undefined; + let timeoutId, hasErrored = false; try { // Give the server 5 seconds to respond, otherwise cancel this and throw an // error to the console. The fetch request will also throw an error immediately @@ -79,18 +90,33 @@ for (let i = 2; i < process.argv.length; i++) clearTimeout(timeoutId); if (response === "Error") throw new Error("Server is unresponsive."); } catch (e) { +// Remove the temporary shutdown file since the server didn't remove it. + await unlink(shutdown); // Check if this is the error thrown by the fetch request for an unused port. // Don't print the unused port error, since nothing has actually broken. if (e instanceof TypeError) clearTimeout(timeoutId); - else console.error(e); - await unlink(shutdown); + else { + console.error(e); +// Stop here unless Node will be killed later. + if (!process.argv.slice(i + 1).includes("kill")) + hasErrored = true; + } } // Do not run this if Node will be killed later in this script. It will fail. if (config.production && !process.argv.slice(i + 1).includes("kill")) exec("npx pm2 stop ecosystem.config.js", (error, stdout) => { - if (error) throw error; + if (error) { + console.error(error); + hasErrored = true; + } console.log(stdout); }); +// Do not continue executing commands since the server was unable to be stopped. +// Mostly implemented to prevent duplicating Node instances with npm restart. + if (hasErrored) { + process.exitCode = 1; + break commands; + } break; } @@ -132,4 +158,4 @@ for (let i = 2; i < process.argv.length; i++) } -process.exitCode = 0; +process.exitCode = process.exitCode || 0; diff --git a/src/server.mjs b/src/server.mjs index 27f0bc48..bc0458a7 100644 --- a/src/server.mjs +++ b/src/server.mjs @@ -17,6 +17,7 @@ import loadTemplates from './templates.mjs'; import { fileURLToPath } from 'node:url'; import { existsSync, unlinkSync } from 'node:fs'; import ecosystem from '../ecosystem.config.js'; +import { createBareServer } from "@tomphttp/bare-server-node"; const config = Object.freeze( JSON.parse(await readFile(new URL("./config.json", import.meta.url))) From 2ce0debccc24408cf296a71ad9458a7d6ffd2bfa Mon Sep 17 00:00:00 2001 From: 00Fjongl <65314359+00Fjongl@users.noreply.github.com> Date: Thu, 8 Aug 2024 19:19:19 -0500 Subject: [PATCH 2/2] Alright the GitHub workflow works --- src/server.mjs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/server.mjs b/src/server.mjs index bc0458a7..27f0bc48 100644 --- a/src/server.mjs +++ b/src/server.mjs @@ -17,7 +17,6 @@ import loadTemplates from './templates.mjs'; import { fileURLToPath } from 'node:url'; import { existsSync, unlinkSync } from 'node:fs'; import ecosystem from '../ecosystem.config.js'; -import { createBareServer } from "@tomphttp/bare-server-node"; const config = Object.freeze( JSON.parse(await readFile(new URL("./config.json", import.meta.url)))