fix(config): mirror sync restore failure test and tidy warning format

Review follow-ups on #70515: add the parallel failure-injection test for
maybeRecoverSuspiciousConfigReadSync so the sync path has the same
coverage, and move the captured error message inside the suspicious-
reason parentheses in the failure warning so the line no longer reads
'failed: <path> (...): <msg>' (double colon) — it now reads
'failed: <path> (..., <msg>)' with a single trailing colon after 'failed'.
This commit is contained in:
Fred blum
2026-04-23 09:42:05 +03:00
committed by Josh Lehman
parent f8f939cb6e
commit 702a9bd356
2 changed files with 44 additions and 6 deletions

View File

@@ -316,6 +316,44 @@ describe("config observe recovery", () => {
});
});
it("sync recovery records copyFileSync failure instead of falsely claiming restore succeeded", async () => {
await withSuiteHome(async (home) => {
const { deps, configPath, auditPath, warn } = makeDeps(home);
await seedConfigBackup(configPath, recoverableTelegramConfig);
const clobbered = await writeClobberedUpdateChannel(configPath);
const copyError = Object.assign(new Error("EACCES: permission denied"), { code: "EACCES" });
const failingFs: ObserveRecoveryDeps["fs"] = {
...deps.fs,
copyFileSync: () => {
throw copyError;
},
};
const recovered = maybeRecoverSuspiciousConfigReadSync({
deps: { ...deps, fs: failingFs },
configPath,
raw: clobbered.raw,
parsed: clobbered.parsed,
});
expect((recovered.parsed as { gateway?: { mode?: string } }).gateway?.mode).toBe("local");
await expect(fsp.readFile(configPath, "utf-8")).resolves.toBe(clobbered.raw);
expect(warn).toHaveBeenCalledWith(
expect.stringContaining("Config auto-restore from backup failed:"),
);
expect(warn).toHaveBeenCalledWith(expect.stringContaining("EACCES: permission denied"));
expect(warn).not.toHaveBeenCalledWith(
expect.stringContaining("Config auto-restored from backup:"),
);
const observe = await readLastObserveEvent(auditPath);
expect(observe?.restoredFromBackup).toBe(false);
expect(observe?.valid).toBe(false);
expect(observe?.restoreErrorCode).toBe("EACCES");
expect(observe?.restoreErrorMessage).toBe("EACCES: permission denied");
});
});
it("dedupes repeated suspicious hashes", async () => {
await withSuiteHome(async (home) => {
const { deps, configPath, auditPath } = makeDeps(home);

View File

@@ -688,9 +688,9 @@ export async function maybeRecoverSuspiciousConfigRead(params: {
);
} else {
params.deps.logger.warn(
`Config auto-restore from backup failed: ${params.configPath} (${suspicious.join(", ")})${
restoreErrorDetails.message ? `: ${restoreErrorDetails.message}` : ""
}`,
`Config auto-restore from backup failed: ${params.configPath} (${suspicious.join(", ")}${
restoreErrorDetails.message ? `; ${restoreErrorDetails.message}` : ""
})`,
);
}
await appendConfigAuditRecord(
@@ -795,9 +795,9 @@ export function maybeRecoverSuspiciousConfigReadSync(params: {
);
} else {
params.deps.logger.warn(
`Config auto-restore from backup failed: ${params.configPath} (${suspicious.join(", ")})${
restoreErrorDetails.message ? `: ${restoreErrorDetails.message}` : ""
}`,
`Config auto-restore from backup failed: ${params.configPath} (${suspicious.join(", ")}${
restoreErrorDetails.message ? `; ${restoreErrorDetails.message}` : ""
})`,
);
}
appendConfigAuditRecordSync(