@@ -804,53 +804,82 @@ private static XContentParser createParser(String mediaType, String content) thr
804
804
805
805
private <T > Publisher <? extends T > handleServerError (Request request , ClientResponse response ) {
806
806
807
- RestStatus status = RestStatus .fromCode (response .statusCode ().value ());
807
+ int statusCode = response .statusCode ().value ();
808
+ RestStatus status = RestStatus .fromCode (statusCode );
809
+ String mediaType = response .headers ().contentType ().map (MediaType ::toString ).orElse (XContentType .JSON .mediaType ());
808
810
809
- return Mono .error (new ElasticsearchStatusException (String .format ("%s request to %s returned error code %s." ,
810
- request .getMethod (), request .getEndpoint (), response .statusCode ().value ()), status ));
811
+ return response .body (BodyExtractors .toMono (byte [].class )) //
812
+ .map (bytes -> new String (bytes , StandardCharsets .UTF_8 )) //
813
+ .flatMap (content -> contentOrError (content , mediaType , status ))
814
+ .flatMap (unused -> Mono
815
+ .error (new ElasticsearchStatusException (String .format ("%s request to %s returned error code %s." ,
816
+ request .getMethod (), request .getEndpoint (), statusCode ), status )));
811
817
}
812
818
813
819
private <T > Publisher <? extends T > handleClientError (String logId , Request request , ClientResponse response ,
814
820
Class <T > responseType ) {
815
821
822
+ int statusCode = response .statusCode ().value ();
823
+ RestStatus status = RestStatus .fromCode (statusCode );
824
+ String mediaType = response .headers ().contentType ().map (MediaType ::toString ).orElse (XContentType .JSON .mediaType ());
825
+
816
826
return response .body (BodyExtractors .toMono (byte [].class )) //
817
827
.map (bytes -> new String (bytes , StandardCharsets .UTF_8 )) //
818
- .flatMap (content -> {
819
- String mediaType = response .headers ().contentType ().map (MediaType ::toString )
820
- .orElse (XContentType .JSON .mediaType ());
821
- RestStatus status = RestStatus .fromCode (response .statusCode ().value ());
822
- try {
823
- ElasticsearchException exception = getElasticsearchException (response , content , mediaType );
824
- if (exception != null ) {
825
- StringBuilder sb = new StringBuilder ();
826
- buildExceptionMessages (sb , exception );
827
- return Mono .error (new ElasticsearchStatusException (sb .toString (), status , exception ));
828
- }
829
- } catch (Exception e ) {
830
- return Mono .error (new ElasticsearchStatusException (content , status ));
831
- }
832
- return Mono .just (content );
833
- }).doOnNext (it -> ClientLogger .logResponse (logId , response .statusCode (), it )) //
828
+ .flatMap (content -> contentOrError (content , mediaType , status )) //
829
+ .doOnNext (content -> ClientLogger .logResponse (logId , response .statusCode (), content )) //
834
830
.flatMap (content -> doDecode (response , responseType , content ));
835
831
}
836
832
837
833
// region ElasticsearchException helper
834
+ /**
835
+ * checks if the given content body contains an {@link ElasticsearchException}, if yes it is returned in a Mono.error.
836
+ * Otherwise the content is returned in the Mono
837
+ *
838
+ * @param content the content to analyze
839
+ * @param mediaType the returned media type
840
+ * @param status the response status
841
+ * @return a Mono with the content or an Mono.error
842
+ */
843
+ private static Mono <String > contentOrError (String content , String mediaType , RestStatus status ) {
844
+
845
+ ElasticsearchException exception = getElasticsearchException (content , mediaType , status );
846
+
847
+ if (exception != null ) {
848
+ StringBuilder sb = new StringBuilder ();
849
+ buildExceptionMessages (sb , exception );
850
+ return Mono .error (new ElasticsearchStatusException (sb .toString (), status , exception ));
851
+ }
852
+
853
+ return Mono .just (content );
854
+ }
855
+
856
+ /**
857
+ * tries to parse an {@link ElasticsearchException} from the given body content
858
+ *
859
+ * @param content the content to analyse
860
+ * @param mediaType the type of the body content
861
+ * @return an {@link ElasticsearchException} or {@literal null}.
862
+ */
838
863
@ Nullable
839
- private ElasticsearchException getElasticsearchException (ClientResponse response , String content , String mediaType )
840
- throws IOException {
864
+ private static ElasticsearchException getElasticsearchException (String content , String mediaType , RestStatus status ) {
841
865
842
- XContentParser parser = createParser (mediaType , content );
843
- // we have a JSON object with an error and a status field
844
- XContentParser .Token token = parser .nextToken (); // Skip START_OBJECT
866
+ try {
867
+ XContentParser parser = createParser (mediaType , content );
868
+ // we have a JSON object with an error and a status field
869
+ XContentParser .Token token = parser .nextToken (); // Skip START_OBJECT
845
870
846
- do {
847
- token = parser .nextToken ();
871
+ do {
872
+ token = parser .nextToken ();
848
873
849
- if (parser .currentName ().equals ("error" )) {
850
- return ElasticsearchException .failureFromXContent (parser );
851
- }
852
- } while (token == XContentParser .Token .FIELD_NAME );
853
- return null ;
874
+ if (parser .currentName ().equals ("error" )) {
875
+ return ElasticsearchException .failureFromXContent (parser );
876
+ }
877
+ } while (token == XContentParser .Token .FIELD_NAME );
878
+
879
+ return null ;
880
+ } catch (IOException e ) {
881
+ return new ElasticsearchStatusException (content , status );
882
+ }
854
883
}
855
884
856
885
private static void buildExceptionMessages (StringBuilder sb , Throwable t ) {
0 commit comments