mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2026-08-21 02:03:30 +00:00
fix(search): complete the query error surface across every endpoint
Four pieces of the same surface: whoosh-compat's emit() documents a two-part host contract: both a parse diagnostic and the QueryEmitError/UnsupportedQueryError pair are user-input errors. Only the latter half was caught; QueryEmitError now maps to SearchQueryError too. Messages pass through a cleanup that strips the library's DIVERGENCES.md references and replaces the fast=True host-configuration advice with user language, so no library-internal vocabulary reaches a searching user. The bulk selection paths (bulk edit, the legacy bulk endpoint, bulk download) reached the backend with no SearchQueryError handler, so a bad date or number in a selection filter raised straight to a DRF 500. They now share the search list endpoint's exact mapping (a new search_query_error_messages helper flattens MultipleSearchQueryErrors in one place), returning the same 400 body for the same bad query. QueryParserError means a whoosh-compat parser bug, not user-fixable input, per its own contract; the list endpoint's blanket handler was converting it to a generic 400. It now re-raises and surfaces as a 500 that monitoring can see. All behavior is pinned test-first: bulk edit and bulk download API tests assert 400s naming the bad value (previously unhandled exceptions), a unit test pins the QueryEmitError mapping, three parametrized checks assert no internal vocabulary leaks for the unsupported query shapes, and a mocked parser-bug test asserts the 500. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WMsn6DgzbvSqh1pwy66VVF
This commit is contained in:
committed by
stumpylog
co-authored by
Claude Fable 5
parent
98edd75220
commit
efb6e4b0f1
@@ -855,6 +855,29 @@ class TestDocumentSearchApi(DirectoriesMixin, APITestCase):
|
||||
results = response.data["results"]
|
||||
self.assertEqual({r["id"] for r in results}, {1, 2})
|
||||
|
||||
@mock.patch("documents.search._backend.parse_user_query")
|
||||
def test_search_parser_bug_surfaces_as_500_not_400(self, m) -> None:
|
||||
"""
|
||||
GIVEN:
|
||||
- The query parser itself fails (a whoosh-compat bug, per
|
||||
QueryParserError's own contract: not user-fixable input)
|
||||
WHEN:
|
||||
- Any search request runs
|
||||
THEN:
|
||||
- The error surfaces as a 500 monitoring can see, never a 400
|
||||
blaming the user for a library defect
|
||||
"""
|
||||
from whoosh_compat.errors import QueryParserError
|
||||
|
||||
m.side_effect = QueryParserError("synthetic parser bug")
|
||||
|
||||
self.client.raise_request_exception = False
|
||||
response = self.client.get("/api/documents/?query=anything")
|
||||
self.assertEqual(
|
||||
response.status_code,
|
||||
status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
)
|
||||
|
||||
@mock.patch("documents.search._backend.TantivyBackend.autocomplete")
|
||||
def test_search_autocomplete_limits(self, m) -> None:
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user