Skip to content

Commit b5e42ef

Browse files
iurisilvioclaude
andauthored
Raise the API error from Project.search instead of KeyError (#556)
* Raise the API error from Project.search and stop search_all at the result window Project.search raises RoboflowError with the API's error message and status code when the search API answers with an error, instead of failing on the missing "results" key. Project.search_all pages with offset and limit only inside the first 10,000 results, the most the project search API serves. The last page shrinks to end there, and the next step raises RoboflowError pointing to Workspace.search_all("project:<project>"), which pages with a continuation token. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Raise the API error from Project.search and leave search_all's paging as it was The project search backend is getting offset paging past the 10,000-result window (roboflow-search), so search_all no longer stops there. What stays is Project.search raising the API's error instead of failing with KeyError on 'results'. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
1 parent c85189e commit b5e42ef

2 files changed

Lines changed: 20 additions & 2 deletions

File tree

‎roboflow/core/project.py‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -755,6 +755,9 @@ def search(
755755
(``"image"`` or ``"video"``); video hits add a signed ``videoUrl`` when ``url``
756756
is requested in ``fields``, while ``url`` itself stays the poster frame.
757757
758+
Raises:
759+
RoboflowError: If the API answers with an error.
760+
758761
Example:
759762
>>> import roboflow
760763
@@ -831,7 +834,7 @@ def search(
831834
json=payload,
832835
)
833836

834-
return data.json()["results"]
837+
return rfapi._json_response_or_raise(data)["results"]
835838

836839
def search_all(
837840
self,

‎tests/test_project.py‎

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from responses.matchers import json_params_matcher
88

99
from roboflow import API_URL
10-
from roboflow.adapters.rfapi import AnnotationSaveError, ImageUploadError
10+
from roboflow.adapters.rfapi import AnnotationSaveError, ImageUploadError, RoboflowError
1111
from roboflow.config import DEFAULT_BATCH_NAME
1212
from tests import PROJECT_NAME, ROBOFLOW_API_KEY, WORKSPACE_NAME, RoboflowTest, ordered
1313

@@ -972,6 +972,21 @@ def test_search_with_annotation_job_params(self):
972972
results = self.project.search()
973973
self.assertEqual(len(results), 2)
974974

975+
def test_search_raises_the_api_error(self):
976+
message = "Invalid search request."
977+
responses.add(
978+
responses.POST,
979+
f"{API_URL}/{WORKSPACE_NAME}/{PROJECT_NAME}/search?api_key={ROBOFLOW_API_KEY}",
980+
json={"error": message},
981+
status=400,
982+
)
983+
984+
with self.assertRaises(RoboflowError) as ctx:
985+
self.project.search()
986+
987+
self.assertEqual(str(ctx.exception), message)
988+
self.assertEqual(ctx.exception.status_code, 400)
989+
975990

976991
class TestZipUpload(RoboflowTest):
977992
def _rfapi_mocks(self, get_status_side_effect=None, get_status_return=None):

0 commit comments

Comments
 (0)