fix(compression): log warnings for unreadable settings rows (#13522)

* fix(compression): log warnings for unreadable settings rows

getCompressionSettings() silently skipped non-string (BLOB) and
invalid-JSON settings rows, making it impossible to diagnose config
drift between the panel and the runtime.

Now logs a warn-level message for each unreadable row, including the
key name and a remediation hint (re-save from the Storage panel).

Also warns when the 'engines' row exists but yields no valid toggles,
so operators know their panel-configured engines map is being silently
replaced by the legacy fallback.

Fixes #13456

* test(compression): cover getCompressionSettings warnings for unreadable rows

The test for #13456 only asserted a stubbed console.warn recorded a
message and never called getCompressionSettings(), so it never
exercised the production change. Seed a BLOB row, an invalid-JSON row,
and an 'engines' row that isn't a usable object, and assert the
resulting warnings; also assert a legitimately empty (but valid)
'engines' map does not warn.

Also stop warning on a valid-but-empty 'engines' row: parseStoredEnginesMap
returns null both for an unreadable row and for a well-formed {} (an
operator who deliberately disabled every engine), so only warn when the
stored value isn't a usable object at all.

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>

---------

Co-authored-by: Koosha Pari <koosha@phenotype.ai>
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
This commit is contained in:
Koosha Paridehpour
2026-09-17 06:43:37 -07:00
committed by GitHub
parent cdcf1d2589
commit 5455740faa
2 changed files with 149 additions and 3 deletions

View File

@@ -656,9 +656,27 @@ export async function getCompressionSettings(): Promise<CompressionConfig> {
const record = toRecord(row);
const key = typeof record.key === "string" ? record.key : null;
const rawValue = typeof record.value === "string" ? record.value : null;
if (!key || rawValue === null) continue;
if (!key || rawValue === null) {
// #13456: non-string values (BLOB from backup/restore/migration tooling) are
// silently ignored — log so operators can diagnose config drift.
if (key && typeof record.value !== "string" && record.value !== null) {
console.warn(
`[COMPRESSION] Settings row '${key}' has non-string value type ` +
`(${typeof record.value}); skipping. This may indicate a backup/restore ` +
`issue — re-save the setting from the Storage panel to fix.`
);
}
continue;
}
const parsed = parseJsonSafe(rawValue);
if (parsed === undefined) continue;
if (parsed === undefined) {
// #13456: invalid JSON is also silently ignored — log it.
console.warn(
`[COMPRESSION] Settings row '${key}' has unparseable JSON value; skipping. ` +
`Re-save the setting from the Storage panel to fix.`
);
continue;
}
switch (key) {
case "enabled":
@@ -768,6 +786,16 @@ export async function getCompressionSettings(): Promise<CompressionConfig> {
break;
case "engines":
storedEngines = parseStoredEnginesMap(parsed);
// #13456: only warn when the row itself isn't a usable object — a valid object
// that simply yields zero toggles (e.g. `{}`, an operator deliberately disabling
// every engine) is legitimate config, not a parse failure, and must not warn.
if (storedEngines === null && (!parsed || typeof parsed !== "object")) {
console.warn(
`[COMPRESSION] 'engines' settings row is present but unreadable; ` +
`falling back to legacy settings. Re-save the engines map from the ` +
`Storage panel to fix.`
);
}
break;
case "activeComboId":
config.activeComboId = typeof parsed === "string" && parsed.trim() ? parsed.trim() : null;
@@ -917,7 +945,10 @@ let proactiveRatioCache: { value: number; readAt: number } | null = null;
export function getProactiveCompressionRatio(): number {
const now = Date.now();
if (proactiveRatioCache && now - proactiveRatioCache.readAt < PROACTIVE_COMPRESSION_CACHE_TTL_MS) {
if (
proactiveRatioCache &&
now - proactiveRatioCache.readAt < PROACTIVE_COMPRESSION_CACHE_TTL_MS
) {
return proactiveRatioCache.value;
}
let ratio = PROACTIVE_COMPRESSION_DEFAULT_RATIO;