Skip to content

Fix: del of a missing key was silent; getitem masked backend errors as KeyError - #3

Merged
thorwhalen merged 1 commit into
masterfrom
fix/missing-key-delete-and-getitem-masking
Sep 22, 2026
Merged

thorwhalen merged 1 commit into
masterfrom
fix/missing-key-delete-and-getitem-masking

Conversation

@thorwhalen

Copy link
Copy Markdown
Member

Post-merge refute review of #2.

Defect 1, missing-key delete. #2 maps a NoSuchKey error code to NoSuchKeyError in both __delitem__s. DynamoDB never raises that. NoSuchKey is an S3 code, and DynamoDB's DeleteItem succeeds silently on an absent key. So del store['missing'] still does nothing and does not raise KeyError as the MutableMapping contract requires. It is now delete_item(..., ReturnValues='ALL_OLD'), which raises NoSuchKeyError when no old Attributes come back. That costs no extra request.

Defect 2, getitem masking. #2's new ItemsView.__contains__ goes through .get. All three __getitem__s turned every exception into NoSuchKeyError, including throttling, bad credentials and a missing table. So .get(k) and (k, v) in store.items() reported a present key as absent whenever the backend hiccuped. That is the same masking #2 set out to remove from delete. Now only a response without Item, or a key the schema rejects (ValidationException, e.g. wrong type or empty string, which is what the old code answered as absent), is a KeyError. Everything else propagates.

Tests (in tests/test_offline.py, with the FakeTable now mimicking boto3's ReturnValues): del of a missing key raises KeyError for base and partition stores; a throttled GetItem propagates from [], .get and the items view; ValidationException stays a KeyError; missing-key get/in behave the same as before. 4 of the new tests fail on master. All 19 pass here, plus the helper doctests.

Note: k in store itself is dol.Collection.__contains__, a full scan. That is pre-existing and not changed here.

Self-reviewed only (the dispatching run disallowed sub-agents). No live DynamoDB used.

🤖 Generated with Claude Code

… longer KeyErrors

DynamoDB DeleteItem succeeds silently on an absent key (NoSuchKey is an S3
code), so #2's NoSuchKey mapping never fired: del store[missing] did nothing.
Delete now asks for ReturnValues=ALL_OLD and raises NoSuchKeyError when nothing
was deleted. __getitem__ no longer turns every exception (throttling, auth,
missing table) into NoSuchKeyError, which made .get() and the items view that
#2 added report present keys as absent; only a missing Item or a key the schema
rejects (ValidationException) is a KeyError now.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@thorwhalen
thorwhalen merged commit 6c44494 into master Sep 22, 2026
12 checks passed
@thorwhalen
thorwhalen deleted the fix/missing-key-delete-and-getitem-masking branch September 22, 2026 14:12
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.

1 participant