Upgraded all dependencies
[facebook-utils] / src / main / java / de / juplo / facebook / GraphApiErrorHandler.java
index ce4c98c..2864843 100644 (file)
@@ -1,11 +1,16 @@
 package de.juplo.facebook;
 
+import java.io.ByteArrayInputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.util.List;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
 import org.springframework.http.client.ClientHttpResponse;
 import org.springframework.http.converter.HttpMessageConverter;
 import org.springframework.http.converter.HttpMessageNotReadableException;
 import org.springframework.security.oauth2.client.http.OAuth2ErrorHandler;
+import org.springframework.util.FileCopyUtils;
 import org.springframework.web.client.HttpMessageConverterExtractor;
 import org.springframework.web.client.RestClientException;
 import org.springframework.web.client.RestTemplate;
@@ -45,35 +50,98 @@ public class GraphApiErrorHandler extends OAuth2ErrorHandler
   @Override
   public boolean hasError(ClientHttpResponse response) throws IOException
   {
-    return errorHandler.hasError(response);
+    return
+        HttpStatus.Series.CLIENT_ERROR.equals(response.getStatusCode().series())
+        || this.errorHandler.hasError(response);
   }
 
   @Override
-  public void handleError(ClientHttpResponse response) throws IOException
+  public void handleError(final ClientHttpResponse response) throws IOException
   {
-    HttpMessageConverterExtractor<GraphApiException> extractor =
-        new HttpMessageConverterExtractor<>(
-            GraphApiException.class,
-            messageConverters
-            );
-
-    try
+    if (!HttpStatus.Series.CLIENT_ERROR.equals(response.getStatusCode().series()))
     {
-      GraphApiException body = extractor.extractData(response);
-      if (body != null)
-      {
-        // If we can get an OAuth2Exception already from the body, it is likely
-        // to have more information than the header does, so just re-throw it
-        // here.
-        body.setHttpErrorCode(response.getRawStatusCode());
-        throw body;
-      }
+      // We should only care about 400 level errors. Ex: A 500 server error shouldn't
+      // be an oauth related error.
+      errorHandler.handleError(response);
     }
-    catch (RestClientException|HttpMessageNotReadableException e)
+    else
     {
-      // ignore
-    }
+      // Need to use buffered response because input stream may need to be consumed multiple times.
+      ClientHttpResponse bufferedResponse = new ClientHttpResponse()
+      {
+        private byte[] lazyBody;
+
+        @Override
+        public HttpStatus getStatusCode() throws IOException
+        {
+          return response.getStatusCode();
+        }
+
+        @Override
+        public synchronized InputStream getBody() throws IOException
+        {
+          if (lazyBody == null) {
+            InputStream bodyStream = response.getBody();
+            if (bodyStream != null) {
+              lazyBody = FileCopyUtils.copyToByteArray(bodyStream);
+            }
+            else {
+              lazyBody = new byte[0];
+            }
+          }
+          return new ByteArrayInputStream(lazyBody);
+        }
+
+        @Override
+        public HttpHeaders getHeaders()
+        {
+          return response.getHeaders();
+        }
+
+        @Override
+        public String getStatusText() throws IOException
+        {
+          return response.getStatusText();
+        }
+
+        @Override
+        public void close()
+        {
+          response.close();
+        }
 
-    errorHandler.handleError(response);
+        @Override
+        public int getRawStatusCode() throws IOException
+        {
+          return response.getRawStatusCode();
+        }
+      };
+
+
+      HttpMessageConverterExtractor<GraphApiException> extractor =
+          new HttpMessageConverterExtractor<>(
+              GraphApiException.class,
+              messageConverters
+              );
+
+      try
+      {
+        GraphApiException body = extractor.extractData(bufferedResponse);
+        if (body != null)
+        {
+          // If we can get an OAuth2Exception already from the body, it is likely
+          // to have more information than the header does, so just re-throw it
+          // here.
+          body.setHttpErrorCode(response.getRawStatusCode());
+          throw body;
+        }
+      }
+      catch (RestClientException|HttpMessageNotReadableException e)
+      {
+        // ignore
+      }
+
+      errorHandler.handleError(bufferedResponse);
+    }
   }
 }