fix(patreon): full-fetch fallback when sparse fieldset returns null content (#842)
CI / lint (push) Successful in 3s
CI / frontend-build (push) Successful in 25s
CI / backend-lint-and-test (push) Successful in 1m0s
CI / integration (push) Successful in 3m27s

Operator-flagged: 9 StickySpoodge posts had empty bodies in FC despite the body
plainly existing + being accessible (creds refresh didn't help). All 9 are
body-only / poll / embed / announcement posts with no downloadable gallery
media — Patreon's detail endpoint returns content:null for these under the
sparse fields[post]=content request even though the body exists.

fetch_post_detail_content now re-fetches the FULL post resource once when the
sparse request comes back empty: recovers the body when the sparse fieldset was
the cause, and logs post_type when even the full resource is empty (body lives
elsewhere). Only the empty cases pay the extra GET; the 126 already-working
posts keep the fast sparse path.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-14 22:26:56 -04:00
parent b999480db5
commit 3df191e255
2 changed files with 54 additions and 5 deletions
+22
View File
@@ -380,6 +380,28 @@ def test_fetch_post_detail_content_empty_body_is_none(monkeypatch):
assert client.fetch_post_detail_content("42") is None
def test_fetch_post_detail_content_falls_back_to_full_fetch(monkeypatch):
"""#842: when the sparse fields[post]=content request returns null (Patreon
does this for polls / embeds / body-only posts), a one-time FULL re-fetch
recovers the body — so inline-only / no-media posts still get their text."""
client = PatreonClient(cookies_path=None)
seen_params: list = []
def _get(url, params=None, timeout=None):
seen_params.append(params or {})
if "fields[post]" in (params or {}):
return _FakeResp(200, json_data={"data": {"attributes": {"content": None}}})
return _FakeResp(200, json_data={
"data": {"attributes": {"content": "<p>body via full</p>", "post_type": "poll"}}
})
monkeypatch.setattr(client._session, "get", _get)
assert client.fetch_post_detail_content("42") == "<p>body via full</p>"
# Sparse request first, then a full re-fetch without the sparse fieldset.
assert "fields[post]" in seen_params[0]
assert "fields[post]" not in seen_params[1]
def test_fetch_post_detail_content_blank_id_skips_request(monkeypatch):
calls: list = []
client = PatreonClient(cookies_path=None)