private static String parseErrorCause(JsonObject error) {

		StringBuilder buf = new StringBuilder();

		JsonElement reason = error.get("reason");

		String typeString = convertToString(error.get("type"));
		if (typeString != null) {
			String reasonString = convertToString(reason); // "reason" is string when "type" is present
			String errorStr = typeString + " : " + reasonString;
			conditionalNewLine(buf).append(errorStr);
		}

		JsonElement scriptStack = error.get("script_stack");
		if (scriptStack instanceof JsonArray scriptStackArray) {
			scriptStackArray
					.forEach(e -> conditionalNewLine(buf).append("   ").append(convertToString(e)));
		}

		JsonElement causedBy = error.get("caused_by");
		if (causedBy instanceof JsonObject causedByObject) {
			conditionalNewLine(buf).append("   ").append(parseErrorCause(causedByObject));
		}

		JsonElement failedShards = error.get("failed_shards");
		if (failedShards instanceof JsonArray failedShardsArray) {
			for (JsonElement failedShardElement : failedShardsArray) {
				JsonObject failedShard = (JsonObject) failedShardElement;
				String indexStr = convertToString(failedShard.get("index"));
				conditionalNewLine(buf).append("   Failed shard index: ").append(indexStr);
				conditionalNewLine(buf).append("   ").append(parseErrorCause(failedShard));
			}
		}

		if (reason instanceof JsonObject reasonObject) {
			conditionalNewLine(buf).append(parseErrorCause(reasonObject));
		}

		return buf.toString();
	}
Elastic search sends a JSON document in the Http error stream for any error
Pull out relevant info from the document and construct an exception message
@param resp is the parsed error document
@return the exception String
Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/elastic/ElasticConnection.java