Skip to content

Commit 2dbb8a0

Browse files
committed
feat: Add HTTPError exception handling when Solr returns bad responses
1 parent 7d55506 commit 2dbb8a0

File tree

2 files changed

+46
-33
lines changed

2 files changed

+46
-33
lines changed

pysolr.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1314,6 +1314,19 @@ def _send_request(self, url, params=None, headers=None):
13141314
)
13151315
resp.raise_for_status()
13161316
return resp.json()
1317+
1318+
except requests.exceptions.HTTPError as e:
1319+
error_url = e.response.url
1320+
error_msg = e.response.text
1321+
error_code = e.response.status_code
1322+
1323+
self.log.exception(
1324+
"Solr returned HTTP error %s for URL %s", error_code, error_url
1325+
)
1326+
raise SolrError(
1327+
f"Solr returned HTTP error {error_code}. Response body: {error_msg}"
1328+
)
1329+
13171330
except requests.exceptions.JSONDecodeError as e:
13181331
self.log.exception("Failed to decode JSON response from Solr at %s", url)
13191332
raise SolrError(

tests/test_admin.py

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -128,27 +128,30 @@ def test_status__nonexistent_core_returns_empty_response(self):
128128
self.assertNotIn("instanceDir", result["status"]["not_exists"])
129129

130130
def test_create__existing_core_raises_error(self):
131-
"""Test creating a core that already exists returns a 500 error."""
131+
"""Test creating a core that already exists raises SolrError."""
132132

133133
# First create succeeds
134134
self.solr_admin.create("demo_core1")
135135

136-
# Creating the same core again should return a 500 error response
137-
result = self.solr_admin.create("demo_core1")
136+
# Second create should raise SolrError
137+
with self.assertRaises(SolrError) as ctx:
138+
self.solr_admin.create("demo_core1")
138139

139-
self.assertEqual(result["responseHeader"]["status"], 500)
140-
self.assertEqual(
141-
result["error"]["msg"], "Core with name 'demo_core1' already exists."
140+
self.assertIn("Solr returned HTTP error 500", str(ctx.exception))
141+
self.assertIn(
142+
"Core with name 'demo_core1' already exists",
143+
str(ctx.exception),
142144
)
143145

144146
def test_reload__nonexistent_core_raises_error(self):
145-
"""Test that reloading a non-existent core returns a 400 error."""
146-
result = self.solr_admin.reload("not_exists")
147+
"""Test that reloading a non-existent core raises SolrError."""
148+
149+
with self.assertRaises(SolrError) as ctx:
150+
self.solr_admin.reload("not_exists")
147151

148-
# Solr returns a 400 error for missing cores
149-
self.assertEqual(result["responseHeader"]["status"], 400)
150-
self.assertIn("No such core", result["error"]["msg"])
151-
self.assertIn("not_exists", result["error"]["msg"])
152+
self.assertIn("Solr returned HTTP error 400", str(ctx.exception))
153+
self.assertIn("No such core", str(ctx.exception))
154+
self.assertIn("not_exists", str(ctx.exception))
152155

153156
def test_rename__nonexistent_core_no_effect(self):
154157
"""
@@ -170,40 +173,37 @@ def test_rename__nonexistent_core_no_effect(self):
170173
self.assertNotIn("instanceDir", result["status"]["demo_core99"])
171174

172175
def test_swap__missing_source_core_returns_error(self):
173-
"""Test swapping when the source core is missing returns a 400 error."""
176+
"""Test swapping when the source core is missing raises SolrError."""
174177

175178
# Create only the target core
176179
self.solr_admin.create("demo_core2")
177180

178-
# Attempt to swap a missing source core with an existing target core
179-
result = self.solr_admin.swap("not_exists", "demo_core2")
181+
with self.assertRaises(SolrError) as ctx:
182+
self.solr_admin.swap("not_exists", "demo_core2")
180183

181-
# Solr returns a 400 error when the source core does not exist
182-
self.assertEqual(result["responseHeader"]["status"], 400)
183-
self.assertIn("No such core", result["error"]["msg"])
184-
self.assertIn("not_exists", result["error"]["msg"])
184+
self.assertIn("Solr returned HTTP error 400", str(ctx.exception))
185+
self.assertIn("No such core", str(ctx.exception))
186+
self.assertIn("not_exists", str(ctx.exception))
185187

186188
def test_swap__missing_target_core_returns_error(self):
187-
"""Test swapping when the target core is missing returns a 400 error."""
189+
"""Test swapping when the target core is missing raises SolrError."""
188190

189191
# Create only the source core
190192
self.solr_admin.create("demo_core1")
191193

192-
# Attempt to swap with a missing target core
193-
result = self.solr_admin.swap("demo_core1", "not_exists")
194+
with self.assertRaises(SolrError) as ctx:
195+
self.solr_admin.swap("demo_core1", "not_exists")
194196

195-
# Solr returns a 400 error when the target core does not exist
196-
self.assertEqual(result["responseHeader"]["status"], 400)
197-
self.assertIn("No such core", result["error"]["msg"])
198-
self.assertIn("not_exists", result["error"]["msg"])
197+
self.assertIn("Solr returned HTTP error 400", str(ctx.exception))
198+
self.assertIn("No such core", str(ctx.exception))
199+
self.assertIn("not_exists", str(ctx.exception))
199200

200201
def test_unload__nonexistent_core_returns_error(self):
201-
"""Test unloading a non-existent core returns a 400 error response."""
202+
"""Test unloading a non-existent core raises SolrError."""
202203

203-
# Attempt to unload a core that does not exist
204-
result = self.solr_admin.unload("not_exists")
204+
with self.assertRaises(SolrError) as ctx:
205+
self.solr_admin.unload("not_exists")
205206

206-
# Solr returns a 400 error for unloading a missing core
207-
self.assertEqual(result["responseHeader"]["status"], 400)
208-
self.assertIn("Cannot unload non-existent core", result["error"]["msg"])
209-
self.assertIn("not_exists", result["error"]["msg"])
207+
self.assertIn("Solr returned HTTP error 400", str(ctx.exception))
208+
self.assertIn("Cannot unload non-existent core", str(ctx.exception))
209+
self.assertIn("not_exists", str(ctx.exception))

0 commit comments

Comments
 (0)