SOLR-18175: Return BAD_REQUEST for FieldExistsQuery IllegalStateException#4369
SOLR-18175: Return BAD_REQUEST for FieldExistsQuery IllegalStateException#4369openworld-maker wants to merge 1 commit intoapache:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Updates Solr’s QueryComponent error handling so that FieldExistsQuery execution failures that currently surface as server errors are instead returned as 400 BAD_REQUEST.
Changes:
- Add targeted mapping for
IllegalStateExceptionwhose (possibly nested) message starts withFieldExistsQuery requires..., converting it toSolrException(BAD_REQUEST)in both grouped and ungrouped execution paths. - Introduce a helper method and constant to detect this specific failure signature.
- Add a new unit test class to validate BAD_REQUEST mapping for direct and nested
IllegalStateExceptioncases.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java | Adds the narrow IllegalStateException → BAD_REQUEST remapping for grouped and ungrouped query execution. |
| solr/core/src/test/org/apache/solr/handler/component/QueryComponentFieldExistsQueryErrorHandlingTest.java | Adds tests for the ungrouped execution path to ensure correct exception mapping behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| Method method = | ||
| QueryComponent.class.getDeclaredMethod( | ||
| "doProcessUngroupedSearch", ResponseBuilder.class, QueryCommand.class); | ||
| method.setAccessible(true); | ||
| method.invoke(new QueryComponent(), rb, cmd); |
There was a problem hiding this comment.
This test uses reflection with setAccessible(true) to reach a private method, but it isn’t annotated with @SuppressForbidden. The build enables forbidden-apis’ jdk-reflection signatures (see gradle/validation/forbidden-apis.gradle), and similar reflection-based tests in this package suppress it (e.g., AsyncTrackerSemaphoreLeakTest.java:236). Add an appropriate @SuppressForbidden annotation (method or class) with a brief reason to avoid forbidden-apis failures.
| } catch (IllegalStateException e) { | ||
| maybeThrowBadRequestForFieldExistsQueryFailure(e); | ||
| throw e; |
There was a problem hiding this comment.
The PR changes error mapping for the grouped execution path (the groupingSpec != null branch), but the added tests only exercise the ungrouped doProcessUngroupedSearch path. Please add a test that triggers the grouped path and asserts the same BAD_REQUEST mapping, to prevent regressions specific to grouped execution.
|
I have tagged @dsmiley for review. I did look at the tests and they appear very "mock heavy", and we tend as a project to try and minimize the use of mocks where possible, b/c many of our bugs occur when real objects interact with other real objects ;-). There are a lot of mock objects in the tests so I asked copilot about this and got this response:
Could you take a stab at reducing/removing the use of mocks? I know QueryComponent can be tough to work with directly because of how it sets up state through ResponseBuilders etc... If a non mock version isn't feasible, then it's better to have this test, even if it's brittle! |
What this fixes
SOLR-18175 reports that some
FieldExistsQueryfailures are returned as server errors. These should be client errors (400 BAD_REQUEST).Root cause
During query execution,
FieldExistsQuerycan throw anIllegalStateExceptionwith a message starting withFieldExistsQuery requires ...when the field does not support the required data structures. This exception was not being mapped toBAD_REQUESTinQueryComponentexecution paths.Change in this PR
This PR adds a narrow exception mapping in
QueryComponent:If an
IllegalStateException(including nested causes) has a message starting withFieldExistsQuery requires, it is rethrown asSolrException(BAD_REQUEST).All other
IllegalStateExceptions are left unchanged.Tests
Added
QueryComponentFieldExistsQueryErrorHandlingTestcovering:FieldExistsQuery requires ...exception ->BAD_REQUESTFieldExistsQuery requires ...exception ->BAD_REQUESTIllegalStateException-> unchanged behaviorValidation run in Docker included:
TestSolrQueryParserQueryComponent/SearchHandlersuites*QueryComponent*test patternspotlessCheck)