// Path: src/com/winterwell/es/client/agg/AggregationResults.java
// public class AggregationResults {
// 
// 	private String name;
// 	private Map results;
// 
// 	public AggregationResults(String aggName, Map rs) {
// 		this.name = aggName;
// 		this.results = rs;
// 	}
// 
// 	@Override
// 	public String toString() {
// 		return "AggregationResults[ "+name+": "+results+"]";
// 	}
// }
// 
// Path: src/com/winterwell/es/fail/ESBulkException.java
// public class ESBulkException extends ESException {
// 	
// 	private List<Exception> errors;
// 
// 	public List<Exception> getErrors() {
// 		return errors;
// 	}
// 	
// 	public ESBulkException(List<Exception> exs) {
// 		super(exs.size()+" errors", exs.size() > 1? exs.get(0) : null);
// 		this.errors = exs;
// 	}
// 
// 	private static final long serialVersionUID = 1L;
// 
// }
// 
// Path: src/com/winterwell/es/fail/ESException.java
// public class ESException extends WrappedException implements IElasticException {
// 
// 	public transient ESHttpRequest request;
// 
// 	public ESException(String msg, Throwable ex) {
// 		super(msg, ex);
// 	}
// 
// 	public ESException(String msg) {
// 		super(msg, null);
// 	}
// 	
// 
// 	private static final long serialVersionUID = 1L;
// 
// }


import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.winterwell.es.client.agg.AggregationResults;
import com.winterwell.es.fail.ESBulkException;
import com.winterwell.es.fail.ESException;
import com.winterwell.gson.Gson;
import com.winterwell.gson.GsonBuilder;
import com.winterwell.utils.Dep;
import com.winterwell.utils.Printer;
import com.winterwell.utils.StrUtils;
import com.winterwell.utils.Utils;
import com.winterwell.utils.containers.Containers;
import com.winterwell.utils.log.Log;
import com.winterwell.utils.web.IHasJson;
	
	/**
	 * error or null
	 * 
	 * TODO handle bulk-request errors, which are different 
	 * @see #getBulkErrors()  
	 */
	public RuntimeException getError() {
		// HACK! unreliable if deserialising cos req is transient
		if (req instanceof BulkRequestBuilder && error==null) {
			return getBulkErrors();
		}
		return error;
	}
	
	/**
	 * TODO handle bulk-request errors nicely
	 * @return
	 */
	RuntimeException getBulkErrors() {
		List<Exception> errors = new ArrayList<>();
		Map<String, Object> parsedJson = getParsedJson();
		List<Map<String, Map<String, Object>>> items = (List) parsedJson.get("items");
		if (items == null) return null;
		for(Map<String, Map<String, Object>> item : items) {
			for (Map.Entry<String, Map<String, Object>> entry : item.entrySet()) {
				Map<String, Object> values = entry.getValue();
				Map err = (Map) values.get("error");
				if (err == null) continue;
				String errs = err.toString();
// Path: src/com/winterwell/es/client/agg/AggregationResults.java
// public class AggregationResults {
// 
// 	private String name;
// 	private Map results;
// 
// 	public AggregationResults(String aggName, Map rs) {
// 		this.name = aggName;
// 		this.results = rs;
// 	}
// 
// 	@Override
// 	public String toString() {
// 		return "AggregationResults[ "+name+": "+results+"]";
// 	}
// }
// 
// Path: src/com/winterwell/es/fail/ESBulkException.java
// public class ESBulkException extends ESException {
// 	
// 	private List<Exception> errors;
// 
// 	public List<Exception> getErrors() {
// 		return errors;
// 	}
// 	
// 	public ESBulkException(List<Exception> exs) {
// 		super(exs.size()+" errors", exs.size() > 1? exs.get(0) : null);
// 		this.errors = exs;
// 	}
// 
// 	private static final long serialVersionUID = 1L;
// 
// }
// 
// Path: src/com/winterwell/es/fail/ESException.java
// public class ESException extends WrappedException implements IElasticException {
// 
// 	public transient ESHttpRequest request;
// 
// 	public ESException(String msg, Throwable ex) {
// 		super(msg, ex);
// 	}
// 
// 	public ESException(String msg) {
// 		super(msg, null);
// 	}
// 	
// 
// 	private static final long serialVersionUID = 1L;
// 
// }


// Path: src/com/winterwell/es/client/ESHttpResponse.java
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.winterwell.es.client.agg.AggregationResults;
import com.winterwell.es.fail.ESBulkException;
import com.winterwell.es.fail.ESException;
import com.winterwell.gson.Gson;
import com.winterwell.gson.GsonBuilder;
import com.winterwell.utils.Dep;
import com.winterwell.utils.Printer;
import com.winterwell.utils.StrUtils;
import com.winterwell.utils.Utils;
import com.winterwell.utils.containers.Containers;
import com.winterwell.utils.log.Log;
import com.winterwell.utils.web.IHasJson;

	
	/**
	 * error or null
	 * 
	 * TODO handle bulk-request errors, which are different 
	 * @see #getBulkErrors()  
	 */
	public RuntimeException getError() {
		// HACK! unreliable if deserialising cos req is transient
		if (req instanceof BulkRequestBuilder && error==null) {
			return getBulkErrors();
		}
		return error;
	}
	
	/**
	 * TODO handle bulk-request errors nicely
	 * @return
	 */
	RuntimeException getBulkErrors() {
		List<Exception> errors = new ArrayList<>();
		Map<String, Object> parsedJson = getParsedJson();
		List<Map<String, Map<String, Object>>> items = (List) parsedJson.get("items");
		if (items == null) return null;
		for(Map<String, Map<String, Object>> item : items) {
			for (Map.Entry<String, Map<String, Object>> entry : item.entrySet()) {
				Map<String, Object> values = entry.getValue();
				Map err = (Map) values.get("error");
				if (err == null) continue;
				String errs = err.toString();
				ESException ex = new ESException((String)err.get("reason"));				