### Description

InternalComposite.formatObject() can throw an IllegalArgumentException if the format to be applied to a composite key leads to a loss of information (eg, a date histogram with a width of one day is then given a date format of 'YYYY-mm', meaning that multiple buckets from the same month would produce the same key).  This is currently only checked during serialization, meaning that we can do a great deal of work building aggregations only to then throw the result away at the end.  This also causes a problem for converting the `_search` endpoint to using chunked xcontent serialization, as the HTTP response code is the first thing sent back, and so errors that occur during later serialization don't get handled correctly.
server/src/main/java/org/elasticsearch/search/aggregations/bucket/composite/InternalComposite.java
List<DocValueFormat> formats,
            int[] reverseMuls,
            MissingOrder[] missingOrders
        ) throws IOException {
            this.key = new CompositeKey(in);
            this.docCount = in.readVLong();
            this.aggregations = InternalAggregations.readFrom(in);
            this.reverseMuls = reverseMuls;
            this.missingOrders = missingOrders;
            this.sourceNames = sourceNames;
            this.formats = formats;
        }
        @Override
        public void writeTo(StreamOutput out) throws IOException {
            key.writeTo(out);
            out.writeVLong(docCount);
            aggregations.writeTo(out);
        }
        @Override
        public int hashCode() {
            return Objects.hash(getClass(), docCount, key, aggregations);
        }
        @Override
        public boolean equals(Object obj) {
            if (obj == null || getClass() != obj.getClass()) {
                return false;
            }
            InternalBucket that = (InternalBucket) obj;
            return Objects.equals(docCount, that.docCount)
                && Objects.equals(key, that.key)