Harden backup JSON parsing and fix queue display
This commit is contained in:
@@ -30,6 +30,17 @@ async def _unit_status(unit: str, props: list[str]) -> dict[str, str]:
|
||||
return _parse_systemctl_kv(out)
|
||||
|
||||
|
||||
def _load_json(raw: str, label: str) -> tuple[bool, object | None, str]:
|
||||
if not raw or not raw.strip():
|
||||
return False, None, f"? {label} returned empty output"
|
||||
try:
|
||||
return True, json.loads(raw), ""
|
||||
except json.JSONDecodeError:
|
||||
preview = raw.strip().splitlines()
|
||||
head = preview[0] if preview else "invalid output"
|
||||
return False, None, f"? {label} invalid JSON: {head}"
|
||||
|
||||
|
||||
async def send_backup_jobs_status(msg: Message):
|
||||
services = [
|
||||
("backup-auto", "backup-auto.timer"),
|
||||
@@ -78,7 +89,11 @@ async def cmd_repo_stats(msg: Message):
|
||||
await msg.answer(raw1, reply_markup=backup_kb)
|
||||
return
|
||||
|
||||
restore = json.loads(raw1)
|
||||
ok, restore, err = _load_json(raw1, "restic stats")
|
||||
if not ok:
|
||||
await msg.answer(err, reply_markup=backup_kb)
|
||||
return
|
||||
|
||||
|
||||
# --- raw-data stats ---
|
||||
rc2, raw2 = await run_cmd(
|
||||
@@ -90,7 +105,11 @@ async def cmd_repo_stats(msg: Message):
|
||||
await msg.answer(raw2, reply_markup=backup_kb)
|
||||
return
|
||||
|
||||
raw = json.loads(raw2)
|
||||
ok, raw, err = _load_json(raw2, "restic stats raw-data")
|
||||
if not ok:
|
||||
await msg.answer(err, reply_markup=backup_kb)
|
||||
return
|
||||
|
||||
|
||||
# --- snapshots count ---
|
||||
rc3, raw_snaps = await run_cmd(
|
||||
@@ -98,7 +117,14 @@ async def cmd_repo_stats(msg: Message):
|
||||
use_restic_env=True,
|
||||
timeout=20
|
||||
)
|
||||
snaps = len(json.loads(raw_snaps)) if rc3 == 0 else "n/a"
|
||||
if rc3 != 0:
|
||||
snaps = "n/a"
|
||||
else:
|
||||
ok, snap_data, err = _load_json(raw_snaps, "restic snapshots")
|
||||
if ok and isinstance(snap_data, list):
|
||||
snaps = len(snap_data)
|
||||
else:
|
||||
snaps = "n/a"
|
||||
|
||||
msg_text = (
|
||||
"📦 **Repository stats**\n\n"
|
||||
@@ -124,7 +150,10 @@ async def cmd_backup_status(msg: Message):
|
||||
await msg.answer(raw, reply_markup=backup_kb)
|
||||
return
|
||||
|
||||
snaps = json.loads(raw)
|
||||
ok, snaps, err = _load_json(raw, "restic snapshots")
|
||||
if not ok or not isinstance(snaps, list):
|
||||
await msg.answer(err, reply_markup=backup_kb)
|
||||
return
|
||||
if not snaps:
|
||||
await msg.answer("📦 Snapshots: none", reply_markup=backup_kb)
|
||||
return
|
||||
@@ -193,7 +222,10 @@ async def cmd_last_snapshot(msg: Message):
|
||||
await msg.answer(raw, reply_markup=backup_kb)
|
||||
return
|
||||
|
||||
snaps = json.loads(raw)
|
||||
ok, snaps, err = _load_json(raw, "restic snapshots")
|
||||
if not ok or not isinstance(snaps, list):
|
||||
await msg.answer(err, reply_markup=backup_kb)
|
||||
return
|
||||
if not snaps:
|
||||
await msg.answer("📦 Snapshots: none", reply_markup=backup_kb)
|
||||
return
|
||||
@@ -212,7 +244,10 @@ async def cmd_last_snapshot(msg: Message):
|
||||
await msg.answer(raw2, reply_markup=backup_kb)
|
||||
return
|
||||
|
||||
stats = json.loads(raw2)
|
||||
ok, stats, err = _load_json(raw2, f"restic stats {short_id}")
|
||||
if not ok or not isinstance(stats, dict):
|
||||
await msg.answer(err, reply_markup=backup_kb)
|
||||
return
|
||||
|
||||
msg_text = (
|
||||
"📦 **Last snapshot**\n\n"
|
||||
|
||||
Reference in New Issue
Block a user