fix(backup): tell the user when an imported database fails its integrity check

The integrity gate added to _safe_restore_db makes it return False for a
corrupt archive member, but _import_db_member still reported every False as
a live-holder refusal ("Stop the gateway/dashboard processes ..."), sending
users after the wrong fix while the real cause only reached logger.error.
On failure, re-run the bounded integrity check on the extracted temp file
and raise a message naming the actual cause; the holder message is kept for
genuine refusals. The check runs only on the failure path, so successful
imports pay nothing extra. Also document the new False case in the
_safe_restore_db docstring.

Co-authored-by: liuzikaii <2319582736@qq.com>
This commit is contained in:
kshitijk4poor
2026-09-26 19:40:09 +05:30
committed by kshitij
parent 48f1bf7251
commit e9f3ea65ff

View File

@@ -97,6 +97,8 @@ def _safe_restore_db(src: Path, dst: Path) -> bool:
process or in-process connection holds the file: replacing the inode
under a live holder is the #90950 split-brain, so that branch fails
closed (returns ``False``) and the caller reports the file as skipped.
It also returns ``False``, without touching *dst*, when *src* fails the
SQLite integrity check.
"""
from hermes_cli.backup import verify_sqlite_integrity
@@ -462,6 +464,15 @@ def _import_db_member(
dst.flush()
os.fsync(dst.fileno())
if not _safe_restore_db(Path(tmp_name), target):
from hermes_cli.backup import verify_sqlite_integrity
# Re-check only on failure so the user gets the real cause; the
# detailed integrity message was already logged by _safe_restore_db.
if not verify_sqlite_integrity(Path(tmp_name))["valid"]:
raise OSError(
"the archived database failed its integrity check; the existing "
"database was left untouched."
)
raise OSError(
"live-safe restore refused or failed; the existing database was "
"left untouched. Stop the gateway/dashboard processes holding it "