mirror of
https://github.com/MichMich/MagicMirror.git
synced 2025-12-12 01:42:19 +00:00
[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 > magicmirror@2.34.0-develop 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 > magicmirror@2.34.0-develop 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 ```
This commit is contained in:
committed by
GitHub
parent
c9eecddf23
commit
9ad5618843
@@ -18,6 +18,7 @@ planned for 2026-01-01
|
|||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- [core] refactor: replace `module-alias` dependency with internal alias resolver (#3893)
|
- [core] refactor: replace `module-alias` dependency with internal alias resolver (#3893)
|
||||||
|
- [check_config] refactor: improve error handling (#3927)
|
||||||
- [calendar] test: remove "Recurring event per timezone" test (#3929)
|
- [calendar] test: remove "Recurring event per timezone" test (#3929)
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|||||||
@@ -31,16 +31,18 @@ function getConfigFile () {
|
|||||||
function checkConfigFile () {
|
function checkConfigFile () {
|
||||||
const configFileName = getConfigFile();
|
const configFileName = getConfigFile();
|
||||||
|
|
||||||
// Check if file is present
|
// Check if file exists and is accessible
|
||||||
if (fs.existsSync(configFileName) === false) {
|
|
||||||
throw new Error(`File not found: ${configFileName}\nNo config file present!`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check permission
|
|
||||||
try {
|
try {
|
||||||
fs.accessSync(configFileName, fs.constants.F_OK);
|
fs.accessSync(configFileName, fs.constants.R_OK);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new Error(`${error}\nNo permission to access config file!`);
|
if (error.code === "ENOENT") {
|
||||||
|
Log.error(`File not found: ${configFileName}`);
|
||||||
|
} else if (error.code === "EACCES") {
|
||||||
|
Log.error(`No permission to read config file: ${configFileName}`);
|
||||||
|
} else {
|
||||||
|
Log.error(`Cannot access config file: ${configFileName}\n${error.message}`);
|
||||||
|
}
|
||||||
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate syntax of the configuration file.
|
// Validate syntax of the configuration file.
|
||||||
@@ -75,7 +77,8 @@ function checkConfigFile () {
|
|||||||
for (const error of errors) {
|
for (const error of errors) {
|
||||||
errorMessage += `\nLine ${error.line} column ${error.column}: ${error.message}`;
|
errorMessage += `\nLine ${error.line} column ${error.column}: ${error.message}`;
|
||||||
}
|
}
|
||||||
throw new Error(errorMessage);
|
Log.error(errorMessage);
|
||||||
|
process.exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,8 +105,7 @@ function validateModulePositions (configFileName) {
|
|||||||
type: "string"
|
type: "string"
|
||||||
},
|
},
|
||||||
position: {
|
position: {
|
||||||
type: "string",
|
type: "string"
|
||||||
enum: positionList
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
required: ["module"]
|
required: ["module"]
|
||||||
@@ -119,6 +121,16 @@ function validateModulePositions (configFileName) {
|
|||||||
const valid = validate(data);
|
const valid = validate(data);
|
||||||
if (valid) {
|
if (valid) {
|
||||||
Log.info(styleText("green", "Your modules structure configuration doesn't contain errors :)"));
|
Log.info(styleText("green", "Your modules structure configuration doesn't contain errors :)"));
|
||||||
|
|
||||||
|
// Check for unknown positions (warning only, not an error)
|
||||||
|
if (data.modules) {
|
||||||
|
for (const [index, module] of data.modules.entries()) {
|
||||||
|
if (module.position && !positionList.includes(module.position)) {
|
||||||
|
Log.warn(`Module ${index} ("${module.module}") uses unknown position: "${module.position}"`);
|
||||||
|
Log.warn(`Known positions are: ${positionList.join(", ")}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
const module = validate.errors[0].instancePath.split("/")[2];
|
const module = validate.errors[0].instancePath.split("/")[2];
|
||||||
const position = validate.errors[0].instancePath.split("/")[3];
|
const position = validate.errors[0].instancePath.split("/")[3];
|
||||||
@@ -130,13 +142,15 @@ function validateModulePositions (configFileName) {
|
|||||||
} else {
|
} else {
|
||||||
errorMessage += validate.errors[0].message;
|
errorMessage += validate.errors[0].message;
|
||||||
}
|
}
|
||||||
Log.error("[checkconfig]", errorMessage);
|
Log.error(errorMessage);
|
||||||
|
process.exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
checkConfigFile();
|
checkConfigFile();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
Log.error("[checkconfig]", error);
|
const message = error && error.message ? error.message : error;
|
||||||
|
Log.error(`Unexpected error: ${message}`);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user