X-Git-Url: https://juplo.de/gitweb/?p=facebook-utils;a=blobdiff_plain;f=src%2Fmain%2Fjava%2Fde%2Fjuplo%2Ffacebook%2Fclient%2FGraphApiErrorHandler.java;h=6b1ab971af2f98a51b663c4dde39154a403ed173;hp=faff55e569b780b0d5acf6643934c893266b4533;hb=24361a39e7ec511fd621c0fee59263e70ab0c2c9;hpb=bc0989ddb7bb05e2d95ae4aad4438b4d4806f9dc diff --git a/src/main/java/de/juplo/facebook/client/GraphApiErrorHandler.java b/src/main/java/de/juplo/facebook/client/GraphApiErrorHandler.java index faff55e..6b1ab97 100644 --- a/src/main/java/de/juplo/facebook/client/GraphApiErrorHandler.java +++ b/src/main/java/de/juplo/facebook/client/GraphApiErrorHandler.java @@ -4,74 +4,96 @@ import de.juplo.facebook.exceptions.GraphApiException; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; -import java.util.List; +import java.nio.charset.Charset; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; 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 400 BAD REQUEST}. 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 400 BAD REQUEST} 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 static Logger LOG = + LoggerFactory.getLogger(GraphApiErrorHandler.class); - - public GraphApiErrorHandler(OAuth2ErrorHandler errorHandler) - { - super(null); - this.errorHandler = errorHandler; - } + private final ResponseErrorHandler parent; - /** - * @param messageConverters the messageConverters to set - */ - @Override - public void setMessageConverters( - List> messageConverters - ) + public GraphApiErrorHandler(ResponseErrorHandler errorHandler) { - this.messageConverters = messageConverters; - errorHandler.setMessageConverters(messageConverters); + this.parent = errorHandler; } + @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 public void handleError(final ClientHttpResponse response) throws IOException { - if (!HttpStatus.Series.CLIENT_ERROR.equals(response.getStatusCode().series())) + if (!HttpStatus.BAD_REQUEST.equals(response.getStatusCode())) + { + // We will only handle 400 BAD REQUEST + LOG.debug("ignoring response with status-code {}.", response.getStatusCode()); + parent.handleError(response); + return; + } + + + if (response.getBody() == null) { - // We should only care about 400 level errors. Ex: A 500 server error shouldn't - // be an oauth related error. - errorHandler.handleError(response); + // There is no body to interpret in the HTTP-message + LOG.warn("Could not convert the response into an exception, because there is no message-body."); + parent.handleError(response); + return; } - else + + final byte[] body = FileCopyUtils.copyToByteArray(response.getBody()); + GraphApiException error; + + try { - // Need to use buffered response because input stream may need to be consumed multiple times. - ClientHttpResponse bufferedResponse = new ClientHttpResponse() - { - private byte[] lazyBody; + error = GraphApiException.create(body); + if (LOG.isInfoEnabled()) + LOG.info("error-response: {}", new String(body, Charset.forName("UTF-8"))); + } + catch (Exception e) + { + // The body of the HTTP-message could not be parsed. + // Let the parent error-handler try to handle the response. + + LOG.warn("Could not convert the response into an exception, because the body is unparsable: {}", body); + // 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 +103,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 +131,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; } }