From fb2aa438d88ffa03a39a2e33c216ecee48a1af13 Mon Sep 17 00:00:00 2001 From: Kristjan ESPERANTO <35647502+KristjanESPERANTO@users.noreply.github.com> Date: Sat, 13 Sep 2025 13:01:55 +0200 Subject: [PATCH] feat: add clear log for occupied port at startup (#3890) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Having repeatedly seen that users are unaware of the meaning of the EADDRINUSE error message (see, for example, this [forum thread](https://forum.magicmirror.builders/topic/19871/update-package-list/5)), I thought we should intercept this message and provide clearer output. This may help users identify the cause of the problem more quickly themselves. ## before ``` [2025-09-13 09:54:32.903] [LOG] Starting MagicMirror: v2.33.0-develop ... [2025-09-13 09:54:33.533] [LOG] Starting server on port 8080 ... [2025-09-13 09:54:33.537] [WARN] You're using a full whitelist configuration to allow for all IPs [2025-09-13 09:54:33.568] [ERROR] Whoops! There was an uncaught exception... [2025-09-13 09:54:33.574] [ERROR] Error: listen EADDRINUSE: address already in use 0.0.0.0:8080 at Server.setupListenHandle [as _listen2] (node:net:1940:16) at listenInCluster (node:net:1997:12) at node:net:2206:7 at process.processTicksAndRejections (node:internal/process/task_queues:90:21) { code: 'EADDRINUSE', errno: -98, syscall: 'listen', address: '0.0.0.0', port: 8080 } [2025-09-13 09:54:33.574] [ERROR] MagicMirror² will not quit, but it might be a good idea to check why this happened. Maybe no internet connection? [2025-09-13 09:54:33.574] [ERROR] If you think this really is an issue, please open an issue on GitHub: https://github.com/MagicMirrorOrg/MagicMirror/issues [2025-09-13 09:54:35.235] [INFO] #### System Information #### ... ``` ## after ``` [2025-09-13 09:53:20.151] [LOG] Starting MagicMirror: v2.33.0-develop ... [2025-09-13 09:53:20.928] [LOG] Starting server on port 8080 ... [2025-09-13 09:53:20.931] [WARN] You're using a full whitelist configuration to allow for all IPs [2025-09-13 09:53:20.970] [ERROR] ──────────────────────────────────────────────────────────────── PORT IN USE: 0.0.0.0:8080 Another process (most likely another MagicMirror instance) is already using this port. Stop the other process (free the port) or use a different port. ──────────────────────────────────────────────────────────────── [2025-09-13 09:53:22.471] [INFO] #### System Information #### ... ``` --- CHANGELOG.md | 5 +++-- js/server.js | 23 +++++++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e3ec6d8..2b80c802 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,8 +17,9 @@ Thanks to: @dathbe. ### Added -- Added configuration option for `User-Agent`, used by calendar & news module (#3255) -- [linter] Added prettier plugin for nunjuck templates (#3887) +- Add configuration option for `User-Agent`, used by calendar & news module (#3255) +- [linter] Add prettier plugin for nunjuck templates (#3887) +- [core] Add clear log for occupied port at startup (#3890) ### Changed diff --git a/js/server.js b/js/server.js index 3b4e2503..fb17b906 100644 --- a/js/server.js +++ b/js/server.js @@ -55,6 +55,29 @@ function Server (config) { }); Log.log(`Starting server on port ${port} ... `); + + // Add explicit error handling BEFORE calling listen so we can give user-friendly feedback + server.once("error", (err) => { + if (err && err.code === "EADDRINUSE") { + const bindAddr = config.address || "localhost"; + const portInUseMessage = [ + "", + "────────────────────────────────────────────────────────────────", + ` PORT IN USE: ${bindAddr}:${port}`, + "", + " Another process (most likely another MagicMirror instance)", + " is already using this port.", + "", + " Stop the other process (free the port) or use a different port.", + "────────────────────────────────────────────────────────────────" + ].join("\n"); + Log.error(portInUseMessage); + return; + } + + Log.error("Failed to start server:", err); + }); + server.listen(port, config.address || "localhost"); if (config.ipWhitelist instanceof Array && config.ipWhitelist.length === 0) {