You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@solr.apache.org by st...@apache.org on 2023/08/22 16:27:27 UTC
[solr] branch main updated: SOLR-16929 SolrStream propagates undecoded error message (#1852)
This is an automated email from the ASF dual-hosted git repository.
stillalex pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/solr.git
The following commit(s) were added to refs/heads/main by this push:
new c7b58302d33 SOLR-16929 SolrStream propagates undecoded error message (#1852)
c7b58302d33 is described below
commit c7b58302d334795e1c820f2a28903b64bce91e59
Author: Alex D <st...@apache.org>
AuthorDate: Tue Aug 22 09:27:21 2023 -0700
SOLR-16929 SolrStream propagates undecoded error message (#1852)
---
solr/CHANGES.txt | 2 ++
.../solrj/io/stream/JavabinTupleStreamParser.java | 24 +++++++++++--
.../solr/client/solrj/io/stream/SolrStream.java | 3 +-
.../solr/client/solrj/io/stream/StreamingTest.java | 40 ++++++++++++++++++----
4 files changed, 60 insertions(+), 9 deletions(-)
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index e09b1849394..66e12ec7384 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -130,6 +130,8 @@ Bug Fixes
* SOLR-16859: Missing Proxy support for Http2SolrClient (Alex Deparvu)
+* SOLR-16929: SolrStream propagates undecoded error message (Alex Deparvu)
+
Dependency Upgrades
---------------------
diff --git a/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/stream/JavabinTupleStreamParser.java b/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/stream/JavabinTupleStreamParser.java
index 751d833168f..5209d29e4be 100644
--- a/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/stream/JavabinTupleStreamParser.java
+++ b/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/stream/JavabinTupleStreamParser.java
@@ -24,6 +24,7 @@ import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import org.apache.solr.common.util.DataInputInputStream;
import org.apache.solr.common.util.FastInputStream;
import org.apache.solr.common.util.JavaBinCodec;
@@ -34,12 +35,12 @@ public class JavabinTupleStreamParser extends JavaBinCodec implements TupleStrea
private int arraySize = Integer.MAX_VALUE;
private boolean onlyJsonTypes = false;
int objectSize;
+ private boolean atDocs;
public JavabinTupleStreamParser(InputStream is, boolean onlyJsonTypes) throws IOException {
this.onlyJsonTypes = onlyJsonTypes;
this.is = is;
this.fis = initRead(is);
- if (!readTillDocs()) arraySize = 0;
}
private boolean readTillDocs() throws IOException {
@@ -61,6 +62,9 @@ public class JavabinTupleStreamParser extends JavaBinCodec implements TupleStrea
return true;
}
return false;
+ } else if ("error".equals(k)) {
+ handleError();
+ return true;
} else {
if (readTillDocs()) return true;
}
@@ -91,7 +95,7 @@ public class JavabinTupleStreamParser extends JavaBinCodec implements TupleStrea
return tagByte == SOLRDOCLST;
}
- private Map<?, ?> readAsMap(DataInputInputStream dis) throws IOException {
+ private Map<String, ?> readAsMap(DataInputInputStream dis) throws IOException {
int sz = readSize(dis);
Map<String, Object> m = new LinkedHashMap<>();
for (int i = 0; i < sz; i++) {
@@ -175,6 +179,14 @@ public class JavabinTupleStreamParser extends JavaBinCodec implements TupleStrea
@Override
@SuppressWarnings({"unchecked"})
public Map<String, Object> next() throws IOException {
+ if (!atDocs) {
+ atDocs = true;
+ if (!readTillDocs()) {
+ arraySize = 0;
+ return null;
+ }
+ }
+
if (arraySize == 0) return null;
Object o = readVal(fis);
arraySize--;
@@ -186,4 +198,12 @@ public class JavabinTupleStreamParser extends JavaBinCodec implements TupleStrea
public void close() throws IOException {
is.close();
}
+
+ private void handleError() throws IOException {
+ tagByte = fis.readByte();
+ var error = readAsMap(fis);
+ var msg =
+ Optional.ofNullable(error.get("msg")).map(String::valueOf).orElse("Unknown Exception");
+ throw new SolrStream.HandledException(msg);
+ }
}
diff --git a/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/stream/SolrStream.java b/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/stream/SolrStream.java
index f58546cb432..ce4d31babaa 100644
--- a/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/stream/SolrStream.java
+++ b/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/stream/SolrStream.java
@@ -315,7 +315,8 @@ public class SolrStream extends TupleStream {
statusCode = (int) genericResponse.get("responseStatus");
}
- if (statusCode != 200) {
+ if (statusCode == 401
+ || statusCode == 403) { // auth response comes as html, so propagate as string
String errMsg = consumeStreamAsErrorMessage(stream);
if (httpResponse != null) {
httpResponse.close();
diff --git a/solr/solrj-streaming/src/test/org/apache/solr/client/solrj/io/stream/StreamingTest.java b/solr/solrj-streaming/src/test/org/apache/solr/client/solrj/io/stream/StreamingTest.java
index 295fca76f9f..d8770711876 100644
--- a/solr/solrj-streaming/src/test/org/apache/solr/client/solrj/io/stream/StreamingTest.java
+++ b/solr/solrj-streaming/src/test/org/apache/solr/client/solrj/io/stream/StreamingTest.java
@@ -627,7 +627,6 @@ public class StreamingTest extends SolrCloudTestCase {
}
@Test
- @Ignore
public void testExceptionStream() throws Exception {
helloDocsUpdateRequest.commit(cluster.getSolrClient(), COLLECTIONORALIAS);
@@ -635,8 +634,8 @@ public class StreamingTest extends SolrCloudTestCase {
StreamContext streamContext = new StreamContext();
SolrClientCache solrClientCache = new SolrClientCache();
streamContext.setSolrClientCache(solrClientCache);
- // Test an error that comes originates from the /select handler
try {
+ // Test an error that originates from the /select handler
SolrParams sParamsA = params("q", "*:*", "fl", "a_s,a_i,a_f,blah", "sort", "blah asc");
CloudSolrStream stream = new CloudSolrStream(zkHost, COLLECTIONORALIAS, sParamsA);
ExceptionStream estream = new ExceptionStream(stream);
@@ -646,16 +645,45 @@ public class StreamingTest extends SolrCloudTestCase {
assertTrue(t.EXCEPTION);
assertTrue(t.getException().contains("sort param field can't be found: blah"));
- // Test an error that comes originates from the /export handler
- sParamsA = params("q", "*:*", "fl", "a_s,a_i,a_f,score", "sort", "a_s asc", "qt", "/export");
+ sParamsA = params("q", "*:*", "fl", "a_s,a_i,a_f,blah", "sort", "blah asc", "wt", "javabin");
stream = new CloudSolrStream(zkHost, COLLECTIONORALIAS, sParamsA);
estream = new ExceptionStream(stream);
estream.setStreamContext(streamContext);
t = getTuple(estream);
assertTrue(t.EOF);
assertTrue(t.EXCEPTION);
- // The /export handler will pass through a real exception.
- assertTrue(t.getException().contains("undefined field:"));
+ assertTrue(t.getException().contains("sort param field can't be found: blah"));
+
+ // Test an error that originates from the /export handler
+ sParamsA = params("q", "*:*", "fl", "a_s,a_i,a_f,blah", "sort", "blah asc", "qt", "/export");
+ stream = new CloudSolrStream(zkHost, COLLECTIONORALIAS, sParamsA);
+ estream = new ExceptionStream(stream);
+ estream.setStreamContext(streamContext);
+ t = getTuple(estream);
+ assertTrue(t.EOF);
+ assertTrue(t.EXCEPTION);
+ assertTrue(t.getException().contains("sort param field can't be found: blah"));
+
+ // Test an error that originates from the /export handler
+ sParamsA =
+ params(
+ "q",
+ "*:*",
+ "fl",
+ "a_s,a_i,a_f,blah",
+ "sort",
+ "blah asc",
+ "qt",
+ "/export",
+ "wt",
+ "javabin");
+ stream = new CloudSolrStream(zkHost, COLLECTIONORALIAS, sParamsA);
+ estream = new ExceptionStream(stream);
+ estream.setStreamContext(streamContext);
+ t = getTuple(estream);
+ assertTrue(t.EOF);
+ assertTrue(t.EXCEPTION);
+ assertTrue(t.getException().contains("sort param field can't be found: blah"));
} finally {
solrClientCache.close();
}