fix: don't crash uninstall on malformed settings.json (#481)
If settings.json contained invalid JSON, JSON.parse threw a SyntaxError, which has no .code, so the catch rethrew it and crashed the script — after the mode flag and config file were already removed, leaving cleanup half-done. Handle SyntaxError explicitly: warn that the statusLine entry couldn't be removed and leave the file untouched, since invalid JSON can't be safely edited. Adds a regression test that a malformed settings.json exits 0, warns, and is left byte-for-byte intact. Closes #434 Co-authored-by: isaukywhite <50426537+isaukywhite@users.noreply.github.com>
This commit is contained in:
parent
b8f20b8e7c
commit
40e50d9e03
|
|
@ -48,5 +48,12 @@ try {
|
|||
}
|
||||
}
|
||||
} catch (e) {
|
||||
if (e.code !== 'ENOENT') throw e;
|
||||
if (e.code === 'ENOENT') {
|
||||
// no settings.json — nothing to clean
|
||||
} else if (e instanceof SyntaxError) {
|
||||
// ponytail: malformed settings.json — can't safely edit it; leave intact, warn
|
||||
console.warn(`settings.json is malformed — could not remove the ponytail statusLine entry. Remove it manually from: ${settingsPath} (${e.message})`);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,6 +84,28 @@ assert.equal(
|
|||
'a combined statusLine must be left untouched, not partially destroyed',
|
||||
);
|
||||
|
||||
// #434: a malformed settings.json must not crash the script mid-cleanup. It
|
||||
// can't be safely edited, so uninstall warns and leaves the file byte-for-byte
|
||||
// intact instead of throwing a SyntaxError after other state was already removed.
|
||||
const malformedSettings = '{ "statusLine": { "command": "ponytail-statusline.sh", broken';
|
||||
fs.writeFileSync(settingsPath, malformedSettings);
|
||||
|
||||
result = runUninstall(env);
|
||||
assert.equal(
|
||||
result.status,
|
||||
0,
|
||||
`expected exit 0 on malformed settings.json, got:\n${result.stdout}${result.stderr}`,
|
||||
);
|
||||
assert.ok(
|
||||
/malformed/i.test(result.stdout + result.stderr),
|
||||
'must warn that the statusLine entry could not be removed',
|
||||
);
|
||||
assert.equal(
|
||||
fs.readFileSync(settingsPath, 'utf8'),
|
||||
malformedSettings,
|
||||
'malformed settings.json must be left unchanged',
|
||||
);
|
||||
|
||||
// Running on an already-clean machine must not throw.
|
||||
result = runUninstall({ HOME: path.join(temp, 'home-empty'), USERPROFILE: path.join(temp, 'home-empty') });
|
||||
assert.equal(result.status, 0, result.stderr);
|
||||
|
|
|
|||
Loading…
Reference in New Issue