Skip to content

fix(core): report dropped entities and restore the cache on error - #185

Merged
LukasGold merged 3 commits into
mainfrom
fix/183-silent-drop-and-cache-restore
Sep 21, 2026
Merged

LukasGold merged 3 commits into
mainfrom
fix/183-silent-drop-and-cache-restore

Conversation

@LukasGold

@LukasGold LukasGold commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

Fixes #183. Two independent gaps in src/osw/core.py.

Based on fix/175-store-entity-verify (#182), not on main, because the first change touches store_entity_, the same function #182 changes, and the new tests depend on the write verification it adds. GitHub retargets this PR to main once #182 merges.

1. store_entity_ no longer drops an entity silently

Two error paths logged and returned. A plain return is not an exception, so handle_upload_object_ returned normally, the collector loop at src/osw/core.py:2048-2052 recorded nothing, and the entity reached neither StoreEntityResult.pages nor StoreEntityResult.failed. store_entity then returned without raising StoreEntityPartialError, so the caller saw a successful call with fewer pages than entities passed in.

Both conditions now raise, so the existing collector loop records them:

  • get_title(entity_) raises: ValueError, chained from the original exception
  • namespace_ or title_ is None: TypeError, matching the neighbouring raise TypeError for a missing overwrite_class_param

The local _logger.error call in the first branch was removed, because the collector loop already logs every failed entity.

Behaviour change

An entity that met one of these two conditions previously caused no exception. It now contributes to StoreEntityResult.failed, which makes store_entity raise StoreEntityPartialError. A caller that depended on the silent drop will now see the error.

2. load_entity restores the page cache state in a finally block

The state was saved at the start and restored near the end, outside any try. An exception from the calls in between (get_page, get_slot_content, the category schema fetch, fetch_schema, namespace_from_full_title) left the cache in the state set for the load. That is the failure mode of #176: a later get_page can return a revision from before a write.

The body is now wrapped in try and the restore is in finally. Only indentation changed inside the body. ruff format rewrapped two lines that the extra indentation pushed past the line limit.

_fetch_schema had the same pattern and is fixed separately in #180.

Tests

  • tests/test_store_entity_silent_drop.py, 6 tests: title failure reported in both the serial and the parallel path, missing namespace, missing title, a mixed batch where only the failing entity is reported, and a normal-path guard.
  • tests/test_load_entity_cache_restore.py, 8 tests: the cache state survives an exception from get_page for both starting states, the same for an exception raised inside the per-page loop after get_page succeeded, plus normal-path guards.

Both files run offline. Reverting only the try/finally and rerunning tests/test_load_entity_cache_restore.py gives 4 failed, 4 passed. The four that fail are the two get_page cases with disable_cache=True and both page-loop cases. The other four cannot discriminate, because with disable_cache=False the cache is never changed at all.

The page-loop test exists because a test that only raises from get_page would still pass if the try covered just the first statement of the body.

Full unit suite: 231 passed.

Not addressed

load_entity has a separate pre-existing defect at src/osw/core.py:1222-1228: disable_cache=True sets the cache to the opposite of the caller's starting state instead of disabling it. Filed as #186. This PR keeps that behaviour unchanged.

- store_entity_ raises instead of returning when it cannot determine the
  title or the namespace, so the collector loop records the entity
- both cases now appear in StoreEntityResult.failed instead of nowhere
- load_entity restores the page cache state in a finally block
- adds offline regression tests for both paths

Closes #183
@github-actions

github-actions Bot commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

Release preview

No version bump from the current commits (stays at v2.3.3). Use conventional commit types (feat, fix, ...) to trigger a release.

Changelog preview (truncated)

Preview via python-semantic-release and conventional commits.

- the fake page raises from get_slot_content, after get_page succeeded
- shows the finally block covers the whole body, not only its first call
- both new cases fail when the try/finally is removed
- StoreEntityResult.failed falls back to the entity name, uuid or
  'unknown' when the title or the namespace cannot be resolved
- those fallback forms became reachable with the two new raises
Base automatically changed from fix/175-store-entity-verify to main September 21, 2026 09:32
@LukasGold LukasGold closed this Sep 21, 2026
@LukasGold LukasGold reopened this Sep 21, 2026
@LukasGold
LukasGold merged commit e9341f9 into main Sep 21, 2026
23 checks passed
@LukasGold
LukasGold deleted the fix/183-silent-drop-and-cache-restore branch September 21, 2026 09:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

store_entity drops entities on two error paths; load_entity can leave the page cache enabled

1 participant