Fix: robust response parsing and clearer errors in ClientService Detect +OK / -ERR / -ERROR, strip leading tabs, collect response lines reliably and improve exception unwrapping.

This commit is contained in:
Jona Walpert
2026-04-12 10:56:22 +02:00
parent 65a93a8c82
commit 9635ee8ef9
@@ -138,33 +138,64 @@ public class ClientService {
() -> { () -> {
try { try {
writeToTransport(message); writeToTransport(message);
String responseText = null; String responseText = clienttcptransport.read().payload();
logger.info("Raw message '{}'", responseText);
responseText = clienttcptransport.read().payload(); boolean hasStatus = false;
logger.info("Raw message '" + responseText + "'"); boolean success = false;
Boolean success = null; for (String rawLine : responseText.split("\n")) {
int count = 0; String line = rawLine;
for (String line : responseText.split("\n")) { if (!hasStatus) {
if (success == null) {
if ("+OK".equals(line)) { if ("+OK".equals(line)) {
success = true; success = true;
hasStatus = true;
continue; continue;
} else if (("-ERROR").equals(responseText)) {
success = false;
} }
if (line.startsWith("-ERR") || line.startsWith("-ERROR")) {
success = false;
hasStatus = true;
continue; continue;
} else if ("END".equals(line)) { }
// ignore any lines before the status indicator
continue;
}
if ("END".equals(line)) {
break; break;
} }
line = line.replaceFirst("^\t", "");
// strip a single leading tab if present (protocol formatting)
if (line.startsWith("\t")) {
line = line.substring(1);
}
response.add(line); response.add(line);
} }
if (success != null && success) {
return; if (!hasStatus) {
// Fallback for servers that do not place the status on a
// dedicated line: try to detect status markers anywhere
// in the payload to remain compatible with older servers.
if (responseText.contains("+OK")) {
success = true;
hasStatus = true;
} else if (responseText.contains("-ERR")
|| responseText.contains("-ERROR")) {
success = false;
hasStatus = true;
} else { } else {
throw new RuntimeException("Error in " + message + ": " + response); throw new RuntimeException(
"No status line in response for '"
+ message
+ "': "
+ responseText);
} }
}
if (success) {
return;
}
throw new RuntimeException("Error in " + message + ": " + response);
} catch (Exception e) { } catch (Exception e) {
throw getRuntimeException(e); throw getRuntimeException(e);
} }
@@ -200,15 +231,14 @@ public class ClientService {
* @return A RuntimeException representing the cause of the original exception. * @return A RuntimeException representing the cause of the original exception.
*/ */
private static RuntimeException getRuntimeException(Exception e) { private static RuntimeException getRuntimeException(Exception e) {
Throwable reason = e.getCause(); Throwable cause = e.getCause();
RuntimeException re; if (cause == null) {
if (reason == null) { return e instanceof RuntimeException ? (RuntimeException) e : new RuntimeException(e);
reason = e;
} else if (reason instanceof RuntimeException rte) {
re = rte;
} }
re = new RuntimeException(reason); if (cause instanceof RuntimeException) {
return re; return (RuntimeException) cause;
}
return new RuntimeException(cause);
} }
/** /**