Skip to content

Commit 3d952d9

Browse files
committed
fix goodreads import provider error warnings #1362
1 parent 669a069 commit 3d952d9

2 files changed

Lines changed: 54 additions & 2 deletions

File tree

src/integrations/imports/goodreads.py

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,14 @@ def import_data(self):
6565
for row in reader:
6666
try:
6767
self._process_row(row)
68-
except services.ProviderAPIError:
69-
error_msg = f"Error processing entry with ID {row['media_id']} "
68+
except services.ProviderAPIError as error:
69+
row_description = self._row_description(row)
70+
logger.warning(
71+
"Error processing Goodreads entry: %s - %s",
72+
row_description,
73+
error,
74+
)
75+
error_msg = f"Error processing entry: {row_description} - {error}"
7076
self.warnings.append(error_msg)
7177
continue
7278
except Exception as error:
@@ -88,6 +94,19 @@ def import_data(self):
8894
deduplicated_messages = "\n".join(dict.fromkeys(self.warnings))
8995
return imported_counts, deduplicated_messages
9096

97+
def _row_description(self, row):
98+
"""Return a useful label for warnings without assuming Yamtrack fields."""
99+
title = row.get("Title")
100+
book_id = row.get("Book Id")
101+
102+
if title and book_id:
103+
return f"{title} (Goodreads ID {book_id})"
104+
if title:
105+
return title
106+
if book_id:
107+
return f"Goodreads ID {book_id}"
108+
return str(row)
109+
91110
def _process_row(self, row):
92111
"""Process a single row from the CSV file."""
93112
default_source = Sources.HARDCOVER

src/integrations/tests/imports/test_goodreads.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
from pathlib import Path
2+
from unittest.mock import MagicMock, patch
23

4+
import requests
35
from django.contrib.auth import get_user_model
46
from django.test import TestCase
57

68
from app.models import (
79
Book,
10+
Sources,
811
Status,
912
)
13+
from app.providers import services
1014
from integrations.imports import (
1115
goodreads,
1216
)
@@ -45,3 +49,32 @@ def test_stored_progress(self):
4549
read_book = Book.objects.get(status=Status.IN_PROGRESS.value)
4650
self.assertEqual(read_book.status, Status.IN_PROGRESS.value)
4751
self.assertEqual(read_book.progress, 0)
52+
53+
54+
class ImportGoodreadsProviderErrors(TestCase):
55+
"""Test GoodReads provider error handling."""
56+
57+
def setUp(self):
58+
"""Create user for the tests."""
59+
self.credentials = {"username": "test", "password": "12345"}
60+
self.user = get_user_model().objects.create_user(**self.credentials)
61+
62+
@patch("integrations.imports.goodreads.GoodReadsImporter._process_row")
63+
def test_provider_error_warns_with_goodreads_fields(self, mock_process_row):
64+
"""Test provider failures warn and continue without requiring media_id."""
65+
response = MagicMock(status_code=408, text='{"error":"Request timeout"}')
66+
error = requests.exceptions.HTTPError(response=response)
67+
mock_process_row.side_effect = services.ProviderAPIError(
68+
Sources.HARDCOVER.value,
69+
error,
70+
)
71+
72+
with Path(mock_path / "import_goodreads.csv").open("rb") as file:
73+
imported_counts, warnings = goodreads.importer(file, self.user, "new")
74+
75+
self.assertEqual(imported_counts, {})
76+
self.assertIn(
77+
"Ghosts of the Tristan Basin (Powder Mage, #0.8) (Goodreads ID 28825810)",
78+
warnings,
79+
)
80+
self.assertIn("There was an error contacting the Hardcover API", warnings)

0 commit comments

Comments
 (0)