This is an automated email from the ASF dual-hosted git repository. dsmiley pushed a commit to branch branch_10x in repository https://gitbox.apache.org/repos/asf/solr.git
commit 0dc9b3cdc145f2a62256d0f807385093a28d11a5 Author: Serhiy Bzhezytskyy <[email protected]> AuthorDate: Thu Jul 16 16:57:45 2026 +0300 SOLR-3284: fix RemoteSolrException NPE when remoteError is null (#4637) A regression in Solr 10.0 for ConcurrentUpdateSolrClient (cherry picked from commit 59b23fd8f184c867e30d66e7f0eca6bb69e2d6b4) --- .../solr/client/solrj/RemoteSolrException.java | 2 +- .../solr/client/solrj/RemoteSolrExceptionTest.java | 54 ++++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/RemoteSolrException.java b/solr/solrj/src/java/org/apache/solr/client/solrj/RemoteSolrException.java index 4552fe0cd9d..a8110be3c80 100644 --- a/solr/solrj/src/java/org/apache/solr/client/solrj/RemoteSolrException.java +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/RemoteSolrException.java @@ -63,7 +63,7 @@ public final class RemoteSolrException extends SolrException { public RemoteSolrException(String remoteHost, int code, Object remoteError, boolean skipRetry) { super(ErrorCode.getErrorCode(code), "Error from server at " + remoteHost); this.skipRetry = skipRetry; - setDetails(List.of(Map.of("remoteHost", remoteHost, "remoteError", remoteError))); + setDetails(List.of(Utils.makeMap("remoteHost", remoteHost, "remoteError", remoteError))); if (remoteError != null) { String remoteErrorMessageSuffix = getRemoteErrorMessageSuffix(remoteError, ""); if (remoteErrorMessageSuffix.length() > 2) { diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/RemoteSolrExceptionTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/RemoteSolrExceptionTest.java new file mode 100644 index 00000000000..cb211e90925 --- /dev/null +++ b/solr/solrj/src/test/org/apache/solr/client/solrj/RemoteSolrExceptionTest.java @@ -0,0 +1,54 @@ +/* + * 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.client.solrj; + +import java.util.List; +import java.util.Map; +import org.apache.solr.SolrTestCase; +import org.junit.Test; + +/** Unit tests for {@link RemoteSolrException}. */ +public class RemoteSolrExceptionTest extends SolrTestCase { + + /** + * A null remoteError must not throw: it happens whenever the server's error body can't be parsed + * (e.g. ConcurrentUpdateSolrClient passes a null error), and the constructor is expected to + * tolerate it. The consumers of the resulting exception must also tolerate the null. + */ + @Test + public void testNullRemoteErrorDoesNotThrow() { + RemoteSolrException e = new RemoteSolrException("http://host:8983/solr", 500, null); + assertEquals(500, e.code()); + assertNull(e.getRemoteErrorObject()); + + // consumers of the exception must tolerate the null remoteError entry + assertNotNull(e.getMessage()); + List<Map<String, Object>> details = e.getDetails(); + assertEquals(1, details.size()); + assertEquals("http://host:8983/solr", details.get(0).get("remoteHost")); + assertNull(details.get(0).get("remoteError")); + } + + /** A non-null remoteError is still recorded and readable back. */ + @Test + public void testRemoteErrorIsRecorded() { + Map<String, Object> remoteError = Map.of("msg", "boom", "code", 500); + RemoteSolrException e = new RemoteSolrException("http://host:8983/solr", 500, remoteError); + assertEquals(500, e.code()); + assertEquals(remoteError, e.getRemoteErrorObject()); + } +}
