diff --git a/changelog/unreleased/SOLR-18066-enable-hideStackTrace.yml b/changelog/unreleased/SOLR-18066-enable-hideStackTrace.yml new file mode 100644 index 000000000000..17de02a2a456 --- /dev/null +++ b/changelog/unreleased/SOLR-18066-enable-hideStackTrace.yml @@ -0,0 +1,7 @@ +title: Enable hideStackTrace config +type: fixed +authors: + - name: Utsav Parmar +links: + - name: SOLR-18066 + url: https://issues.apache.org/jira/browse/SOLR-18066 diff --git a/solr/core/src/java/org/apache/solr/jersey/CatchAllExceptionMapper.java b/solr/core/src/java/org/apache/solr/jersey/CatchAllExceptionMapper.java index e80c922513ee..506aa0670ac8 100644 --- a/solr/core/src/java/org/apache/solr/jersey/CatchAllExceptionMapper.java +++ b/solr/core/src/java/org/apache/solr/jersey/CatchAllExceptionMapper.java @@ -18,6 +18,7 @@ package org.apache.solr.jersey; import static org.apache.solr.common.SolrException.ErrorCode.getErrorCode; +import static org.apache.solr.jersey.RequestContextKeys.CORE_CONTAINER; import static org.apache.solr.jersey.RequestContextKeys.HANDLER_METRICS; import static org.apache.solr.jersey.RequestContextKeys.SOLR_JERSEY_RESPONSE; import static org.apache.solr.jersey.RequestContextKeys.SOLR_QUERY_REQUEST; @@ -33,6 +34,7 @@ import java.lang.invoke.MethodHandles; import org.apache.solr.client.api.model.SolrJerseyResponse; import org.apache.solr.common.SolrException; +import org.apache.solr.core.CoreContainer; import org.apache.solr.handler.RequestHandlerBase; import org.apache.solr.handler.api.V2ApiUtils; import org.apache.solr.request.SolrQueryRequest; @@ -112,8 +114,7 @@ public static Response buildExceptionResponse( ResponseUtils.getTypedErrorInfo( normalizedException, log, - solrQueryRequest.getCore() != null - && solrQueryRequest.getCore().getCoreContainer().hideStackTrace()); + shouldHideStackTrace(solrQueryRequest, containerRequestContext)); response.responseHeader.status = response.error.code; final String mediaType = V2ApiUtils.getMediaTypeFromWtParam( @@ -121,6 +122,16 @@ public static Response buildExceptionResponse( return Response.status(response.error.code).type(mediaType).entity(response).build(); } + static boolean shouldHideStackTrace( + SolrQueryRequest solrQueryRequest, ContainerRequestContext containerRequestContext) { + if (solrQueryRequest != null && solrQueryRequest.getCore() != null) { + return solrQueryRequest.getCore().getCoreContainer().hideStackTrace(); + } + final CoreContainer coreContainer = + (CoreContainer) containerRequestContext.getProperty(CORE_CONTAINER); + return coreContainer != null && coreContainer.hideStackTrace(); + } + private Response processWebApplicationException(WebApplicationException wae) { return wae.getResponse(); } diff --git a/solr/core/src/test/org/apache/solr/jersey/CatchAllExceptionMapperTest.java b/solr/core/src/test/org/apache/solr/jersey/CatchAllExceptionMapperTest.java new file mode 100644 index 000000000000..4fb602286687 --- /dev/null +++ b/solr/core/src/test/org/apache/solr/jersey/CatchAllExceptionMapperTest.java @@ -0,0 +1,91 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.jersey; + +import static org.apache.solr.jersey.CatchAllExceptionMapper.shouldHideStackTrace; +import static org.apache.solr.jersey.RequestContextKeys.CORE_CONTAINER; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import jakarta.ws.rs.container.ContainerRequestContext; +import org.apache.solr.SolrTestCaseJ4; +import org.apache.solr.core.CoreContainer; +import org.apache.solr.core.SolrCore; +import org.apache.solr.request.SolrQueryRequest; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +/** Unit tests for {@link CatchAllExceptionMapper#shouldHideStackTrace} */ +public class CatchAllExceptionMapperTest extends SolrTestCaseJ4 { + + private SolrCore core; + private CoreContainer coreContainer; + private SolrQueryRequest request; + private ContainerRequestContext ctx; + + @BeforeClass + public static void ensureWorkingMockito() { + assumeWorkingMockito(); + } + + @Before + public void setupMocks() { + core = mock(SolrCore.class); + coreContainer = mock(CoreContainer.class); + request = mock(SolrQueryRequest.class); + ctx = mock(ContainerRequestContext.class); + } + + @Test + public void testShouldHideStackTrace_viaCore() { + when(request.getCore()).thenReturn(core); + when(core.getCoreContainer()).thenReturn(coreContainer); + + when(coreContainer.hideStackTrace()).thenReturn(true); + assertTrue(shouldHideStackTrace(request, ctx)); + + when(coreContainer.hideStackTrace()).thenReturn(false); + assertFalse(shouldHideStackTrace(request, ctx)); + } + + /** + * SOLR-18066: When no SolrCore is associated with the request (e.g. cluster/collection-level + * endpoints), the CoreContainer from the request context should be consulted instead. + */ + @Test + public void testShouldHideStackTrace_viaCoreContainer_whenCoreIsNull() { + when(ctx.getProperty(CORE_CONTAINER)).thenReturn(coreContainer); + + when(coreContainer.hideStackTrace()).thenReturn(true); + assertTrue(shouldHideStackTrace(request, ctx)); + + when(coreContainer.hideStackTrace()).thenReturn(false); + assertFalse(shouldHideStackTrace(request, ctx)); + } + + @Test + public void testShouldHideStackTrace_returnsFalse_whenNeitherCoreNorContainerAvailable() { + assertFalse(shouldHideStackTrace(request, ctx)); + } + + @Test + public void testShouldHideStackTrace_returnsFalse_whenRequestIsNull() { + assertFalse(shouldHideStackTrace(null, ctx)); + } +}