mirror of
https://github.com/calibrain/shelfmark.git
synced 2026-11-15 21:58:11 +00:00
The start-up reconcile runs at import, before the coordinator starts, inside a try that named five exception types and left out `TypeError`. `main.py` already defines `_IMPORT_OPERATIONAL_ERRORS` for this shape and the other module-level guards use it, so this switches to it. An unexpected `TypeError` from the reconcile would otherwise fail the import of `shelfmark.main`, and the worker would fail to boot on every restart. I didn't use `except Exception` because BLE001 is on and nothing in main.py does. The test reloads main with the reconcile raising `TypeError`, and with `OSError` as the control (that one already passes on main). Full non-e2e suite passes, ruff and basedpyright are clean. Found in a Claude pass over 1.5.0.
40 lines
1.3 KiB
Python
40 lines
1.3 KiB
Python
"""A reconcile that cannot run must never stop the app from starting."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import importlib
|
|
from unittest.mock import patch
|
|
|
|
import pytest
|
|
|
|
from shelfmark.core.logger import CustomLogger
|
|
|
|
|
|
@pytest.mark.parametrize("error", [TypeError("unexpected row shape"), OSError("disk went away")])
|
|
def test_a_failing_startup_reconcile_only_logs_a_warning(error):
|
|
"""The module-level guard in main.py runs before the coordinator starts.
|
|
|
|
An error it does not catch fails the import of shelfmark.main, and the worker then
|
|
fails to boot on every restart.
|
|
"""
|
|
# Patch the class, not main.logger: reloading main builds a new logger object.
|
|
with (
|
|
patch("shelfmark.download.orchestrator.start"),
|
|
patch("shelfmark.download.warmup.start"),
|
|
patch(
|
|
"shelfmark.core.startup_reconcile.reconcile_interrupted_downloads",
|
|
side_effect=error,
|
|
) as reconcile,
|
|
patch.object(CustomLogger, "warning") as warning,
|
|
):
|
|
import shelfmark.main as main
|
|
|
|
importlib.reload(main)
|
|
|
|
# Importing and then reloading runs the module body twice, so only check it was reached.
|
|
assert reconcile.called
|
|
assert any(
|
|
"Could not reconcile interrupted downloads at startup" in str(call.args[0])
|
|
for call in warning.call_args_list
|
|
)
|