X-Git-Url: https://juplo.de/gitweb/?p=facebook-utils;a=blobdiff_plain;f=src%2Fmain%2Fjava%2Fde%2Fjuplo%2Ffacebook%2Fclient%2FGraphApiErrorHandler.java;h=2b73e4918741fd66d29967f50565dd8696344d2c;hp=faff55e569b780b0d5acf6643934c893266b4533;hb=5f2b31dc7f443ab9eb088d3150e2d4903cb40159;hpb=d0accf7044000e7f20e8bd586c3c48ce8c8cef7d diff --git a/src/main/java/de/juplo/facebook/client/GraphApiErrorHandler.java b/src/main/java/de/juplo/facebook/client/GraphApiErrorHandler.java index faff55e..2b73e49 100644 --- a/src/main/java/de/juplo/facebook/client/GraphApiErrorHandler.java +++ b/src/main/java/de/juplo/facebook/client/GraphApiErrorHandler.java @@ -4,56 +4,48 @@ import de.juplo.facebook.exceptions.GraphApiException; 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; +import org.springframework.web.client.ResponseErrorHandler; /** + * Error-Handler for error-messages from the Facebook Graph-API. + *

+ * This error-handler handels responses withe the HTTP-status code + * {@code 4xx}. It tries to extract and parse the error-message + * from the HTTP-body. Successfully extracted and parsed messages are mapped + * to a hierarchy of exceptions, that reflects the hierarchy of the error- + * codes and -types. + *

+ * If the HTTP-status-code of the response is not {@code 4xx} or + * the HTTP-body could not be extracted or parsed, this error-handler + * delegates the handling to its parent. * - * @author kai + * @see Graph-API Documentation + * @see Inofficial Wiki For Facebook-Developers + * @author Kai Moritz */ -public class GraphApiErrorHandler extends OAuth2ErrorHandler +public class GraphApiErrorHandler implements ResponseErrorHandler { - private final OAuth2ErrorHandler errorHandler; - private List> messageConverters = - new RestTemplate().getMessageConverters(); + private final ResponseErrorHandler parent; - public GraphApiErrorHandler(OAuth2ErrorHandler errorHandler) + public GraphApiErrorHandler(ResponseErrorHandler errorHandler) { - super(null); - this.errorHandler = errorHandler; + this.parent = errorHandler; } - /** - * @param messageConverters the messageConverters to set - */ - @Override - public void setMessageConverters( - List> messageConverters - ) - { - this.messageConverters = messageConverters; - errorHandler.setMessageConverters(messageConverters); - } - @Override public boolean hasError(ClientHttpResponse response) throws IOException { return HttpStatus.Series.CLIENT_ERROR.equals(response.getStatusCode().series()) - || this.errorHandler.hasError(response); + || this.parent.hasError(response); } @Override @@ -61,17 +53,36 @@ public class GraphApiErrorHandler extends OAuth2ErrorHandler { if (!HttpStatus.Series.CLIENT_ERROR.equals(response.getStatusCode().series())) { - // We should only care about 400 level errors. Ex: A 500 server error shouldn't - // be an oauth related error. - errorHandler.handleError(response); + // Let the parent-error-handler handle all errors, that are no client + // errors (4xx). + parent.handleError(response); + return; } - else + + + if (response.getBody() == null) { - // Need to use buffered response because input stream may need to be consumed multiple times. - ClientHttpResponse bufferedResponse = new ClientHttpResponse() - { - private byte[] lazyBody; + // There is no body to interpret in the HTTP-message + parent.handleError(response); + return; + } + + final byte[] body = FileCopyUtils.copyToByteArray(response.getBody()); + GraphApiException error; + + try + { + error = GraphApiException.create(body); + } + catch (Exception e) + { + // The body of the HTTP-message could not be parsed. + // Let the parent error-handler try to handle the response. + // To do so, we have to wrap the original response to fill in + // the buffered body, if needed + ClientHttpResponse buffered = new ClientHttpResponse() + { @Override public HttpStatus getStatusCode() throws IOException { @@ -81,16 +92,7 @@ public class GraphApiErrorHandler extends OAuth2ErrorHandler @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); + return new ByteArrayInputStream(body); } @Override @@ -118,31 +120,10 @@ public class GraphApiErrorHandler extends OAuth2ErrorHandler } }; - - HttpMessageConverterExtractor 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); + parent.handleError(buffered); + return; } + + throw error; } }