diff --git a/src/documents/tests/test_api_search.py b/src/documents/tests/test_api_search.py index 230b3f513..196c6f227 100644 --- a/src/documents/tests/test_api_search.py +++ b/src/documents/tests/test_api_search.py @@ -801,6 +801,26 @@ class TestDocumentSearchApi(DirectoriesMixin, APITestCase): self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertIn("invalid-date", str(response.data["query"])) + def test_search_multiple_bad_fields_returns_all_messages(self) -> None: + """ + GIVEN: + - One document added + WHEN: + - Query with multiple bad fields (e.g. invalid date and invalid number) + THEN: + - 400 Bad Request with error messages for every bad field, + so the user can fix them all in one round-trip + """ + response = self.client.get( + "/api/documents/", + {"query": "created:notadate AND asn:notanumber"}, + ) + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) + messages = response.data["query"] + self.assertEqual(len(messages), 2) + self.assertTrue(any("created" in m for m in messages)) + self.assertTrue(any("asn" in m for m in messages)) + @override_settings( TIME_ZONE="UTC", ) diff --git a/src/documents/views.py b/src/documents/views.py index 68f786b6b..6e3a11fbc 100644 --- a/src/documents/views.py +++ b/src/documents/views.py @@ -2610,10 +2610,17 @@ class UnifiedSearchViewSet(DocumentViewSet): except ValidationError: raise except SearchQueryError as e: - # User-fixable query error (e.g. an unparsable date): surface the - # specific message so the user can correct it, rather than a generic - # 400 or silently empty results. - raise ValidationError({"query": [str(e)]}) from e + # User-fixable query error(s) (e.g. unparsable dates/numbers): + # surface every offending field's message, not just the first, + # so the user can fix them all in one round-trip. + from documents.search import MultipleSearchQueryErrors + + messages = ( + [str(sub) for sub in e.errors] + if isinstance(e, MultipleSearchQueryErrors) + else [str(e)] + ) + raise ValidationError({"query": messages}) from e except Exception as e: logger.warning(f"An error occurred listing search results: {e!s}") return HttpResponseBadRequest(