Skip to content

Commit 7b52168

Browse files
dannyvfilmsclaude
andcommitted
Fix comic issues/details vanishing after tracking
- comicvine.comic() discarded the entire cached volume response if either the publisher-recommendations or issues sub-call raised a ProviderAPIError, even though the primary volume details had already been fetched successfully - Comics have no persisted fallback fields (unlike movies/TV, which reconstruct Details from stored Item/credit rows), so hitting the ProviderAPIError fallback in media_details_views wiped Issues and Details entirely - Catch failures in the two secondary sub-calls individually and default to an empty list instead, so a transient rate-limit hit on one endpoint no longer nukes the whole payload Fixes #975 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
1 parent fa1481d commit 7b52168

2 files changed

Lines changed: 46 additions & 2 deletions

File tree

src/app/providers/comicvine.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,18 @@ def comic(media_id):
129129
publisher_id = response.get("publisher", {}).get("id")
130130
publisher_comics = []
131131
if publisher_id:
132-
publisher_comics = get_publisher_comics(publisher_id, media_id)
132+
try:
133+
publisher_comics = get_publisher_comics(publisher_id, media_id)
134+
except services.ProviderAPIError:
135+
logger.warning(
136+
"Failed to fetch publisher comics for volume %s", media_id
137+
)
138+
139+
try:
140+
issues = get_volume_issues(media_id)
141+
except services.ProviderAPIError:
142+
logger.warning("Failed to fetch issues for volume %s", media_id)
143+
issues = []
133144

134145
data = {
135146
"media_id": media_id,
@@ -161,7 +172,7 @@ def comic(media_id):
161172
},
162173
# used for events fetching
163174
"last_issue_id": response["last_issue"]["id"],
164-
"issues": get_volume_issues(media_id),
175+
"issues": issues,
165176
}
166177

167178
cache.set(cache_key, data)

src/app/tests/providers/test_metadata.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1869,6 +1869,39 @@ def test_comic(self):
18691869
response = comicvine.comic("155969")
18701870
self.assertEqual(response["title"], "Ultimate Spider-Man")
18711871

1872+
@patch("app.providers.comicvine.services.api_request")
1873+
def test_comic_survives_issues_provider_error(self, mock_api_request):
1874+
"""A failing issues/recommendations call shouldn't discard volume details."""
1875+
media_id = "provider-error-test"
1876+
cache_key = f"{Sources.COMICVINE.value}_{MediaTypes.COMIC.value}_{media_id}"
1877+
comicvine.cache.delete(cache_key)
1878+
self.addCleanup(comicvine.cache.delete, cache_key)
1879+
1880+
def side_effect(_source, _method, url, **_kwargs):
1881+
if url.endswith("/issues/"):
1882+
raise services.ProviderAPIError(Sources.COMICVINE.value, Exception())
1883+
return {
1884+
"results": {
1885+
"site_detail_url": "https://example.com/volume",
1886+
"name": "Test Volume",
1887+
"last_issue": {"issue_number": "5", "id": 5},
1888+
"description": "",
1889+
"publisher": {"id": None, "name": "Test Publisher"},
1890+
"start_year": "2020",
1891+
"count_of_issues": 5,
1892+
"people": [],
1893+
"date_last_updated": "2024-01-01 00:00:00",
1894+
},
1895+
}
1896+
1897+
mock_api_request.side_effect = side_effect
1898+
1899+
response = comicvine.comic(media_id)
1900+
1901+
self.assertEqual(response["title"], "Test Volume")
1902+
self.assertEqual(response["details"]["publisher"], "Test Publisher")
1903+
self.assertEqual(response["issues"], [])
1904+
18721905
@patch("app.providers.comicvine.services.api_request")
18731906
def test_comic_volume_issues_sort_numerically(self, mock_api_request):
18741907
"""Comic volume issues should use numeric rather than lexical ordering."""

0 commit comments

Comments
 (0)