Skip to content

Commit 9ad5618

Browse files
[check_config] refactor: improve error handling (#3927)
- Combine file existence and permission checks with better error messages - Replace thrown exceptions with clean error output (no stack traces) - Support custom module positions by changing strict validation to warnings - Add missing process.exit(1) after validation errors Users now see clear, actionable error messages without stack traces, and custom region configurations work correctly. ## example before ```bash $ npm run start > [email protected] start > node --run start:x11 [2025-10-22 17:56:06.303] [LOG] Starting MagicMirror: v2.34.0-develop [2025-10-22 17:56:06.304] [LOG] Loading config ... [2025-10-22 17:56:06.304] [LOG] config template file not exists, no envsubst [2025-10-22 17:56:06.356] [ERROR] File not found: /home/kristjan/MagicMirror/config/config.js No config file present! [2025-10-22 17:56:06.356] [ERROR] [checkconfig] Error: Error: ENOENT: no such file or directory, access '/home/kristjan/MagicMirror/config/config.js' No permission to access config file! at checkConfigFile (/home/kristjan/MagicMirror/js/check_config.js:43:9) at Object.<anonymous> (/home/kristjan/MagicMirror/js/check_config.js:138:2) at Module._compile (node:internal/modules/cjs/loader:1714:14) at Module._extensions..js (node:internal/modules/cjs/loader:1848:10) at Module.load (node:internal/modules/cjs/loader:1448:32) at Module._load (node:internal/modules/cjs/loader:1270:12) at c._load (node:electron/js2c/node_init:2:17993) at TracingChannel.traceSync (node:diagnostics_channel:322:14) at wrapModuleLoad (node:internal/modules/cjs/loader:244:24) at Module.require (node:internal/modules/cjs/loader:1470:12) at require (node:internal/modules/helpers:147:16) at loadConfig (/home/kristjan/MagicMirror/js/app.js:126:3) at App.start (/home/kristjan/MagicMirror/js/app.js:291:18) at Object.<anonymous> (/home/kristjan/MagicMirror/js/electron.js:228:7) at Module._compile (node:internal/modules/cjs/loader:1714:14) at Module._extensions..js (node:internal/modules/cjs/loader:1848:10) ``` ## example after ```bash $ npm run start > [email protected] start > node --run start:x11 [2025-10-22 21:33:27.930] [LOG] Starting MagicMirror: v2.34.0-develop [2025-10-22 21:33:27.931] [LOG] Loading config ... [2025-10-22 21:33:27.931] [LOG] config template file not exists, no envsubst [2025-10-22 21:33:27.985] [ERROR] [check_config] File not found: /home/kristjan/MagicMirror/config/config.js ```
1 parent c9eecdd commit 9ad5618

File tree

2 files changed

+28
-13
lines changed

2 files changed

+28
-13
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ planned for 2026-01-01
1818
### Changed
1919

2020
- [core] refactor: replace `module-alias` dependency with internal alias resolver (#3893)
21+
- [check_config] refactor: improve error handling (#3927)
2122
- [calendar] test: remove "Recurring event per timezone" test (#3929)
2223

2324
### Fixed

js/check_config.js

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,18 @@ function getConfigFile () {
3131
function checkConfigFile () {
3232
const configFileName = getConfigFile();
3333

34-
// Check if file is present
35-
if (fs.existsSync(configFileName) === false) {
36-
throw new Error(`File not found: ${configFileName}\nNo config file present!`);
37-
}
38-
39-
// Check permission
34+
// Check if file exists and is accessible
4035
try {
41-
fs.accessSync(configFileName, fs.constants.F_OK);
36+
fs.accessSync(configFileName, fs.constants.R_OK);
4237
} catch (error) {
43-
throw new Error(`${error}\nNo permission to access config file!`);
38+
if (error.code === "ENOENT") {
39+
Log.error(`File not found: ${configFileName}`);
40+
} else if (error.code === "EACCES") {
41+
Log.error(`No permission to read config file: ${configFileName}`);
42+
} else {
43+
Log.error(`Cannot access config file: ${configFileName}\n${error.message}`);
44+
}
45+
process.exit(1);
4446
}
4547

4648
// Validate syntax of the configuration file.
@@ -75,7 +77,8 @@ function checkConfigFile () {
7577
for (const error of errors) {
7678
errorMessage += `\nLine ${error.line} column ${error.column}: ${error.message}`;
7779
}
78-
throw new Error(errorMessage);
80+
Log.error(errorMessage);
81+
process.exit(1);
7982
}
8083
}
8184

@@ -102,8 +105,7 @@ function validateModulePositions (configFileName) {
102105
type: "string"
103106
},
104107
position: {
105-
type: "string",
106-
enum: positionList
108+
type: "string"
107109
}
108110
},
109111
required: ["module"]
@@ -119,6 +121,16 @@ function validateModulePositions (configFileName) {
119121
const valid = validate(data);
120122
if (valid) {
121123
Log.info(styleText("green", "Your modules structure configuration doesn't contain errors :)"));
124+
125+
// Check for unknown positions (warning only, not an error)
126+
if (data.modules) {
127+
for (const [index, module] of data.modules.entries()) {
128+
if (module.position && !positionList.includes(module.position)) {
129+
Log.warn(`Module ${index} ("${module.module}") uses unknown position: "${module.position}"`);
130+
Log.warn(`Known positions are: ${positionList.join(", ")}`);
131+
}
132+
}
133+
}
122134
} else {
123135
const module = validate.errors[0].instancePath.split("/")[2];
124136
const position = validate.errors[0].instancePath.split("/")[3];
@@ -130,13 +142,15 @@ function validateModulePositions (configFileName) {
130142
} else {
131143
errorMessage += validate.errors[0].message;
132144
}
133-
Log.error("[checkconfig]", errorMessage);
145+
Log.error(errorMessage);
146+
process.exit(1);
134147
}
135148
}
136149

137150
try {
138151
checkConfigFile();
139152
} catch (error) {
140-
Log.error("[checkconfig]", error);
153+
const message = error && error.message ? error.message : error;
154+
Log.error(`Unexpected error: ${message}`);
141155
process.exit(1);
142156
}

0 commit comments

Comments
 (0)