1 package de.juplo.facebook.errors;
4 import java.io.ByteArrayInputStream;
5 import java.io.IOException;
6 import java.io.InputStream;
7 import java.nio.charset.Charset;
8 import org.slf4j.Logger;
9 import org.slf4j.LoggerFactory;
10 import org.springframework.http.HttpHeaders;
11 import org.springframework.http.HttpStatus;
12 import org.springframework.http.client.ClientHttpResponse;
13 import org.springframework.util.FileCopyUtils;
14 import org.springframework.web.client.DefaultResponseErrorHandler;
15 import org.springframework.web.client.ResponseErrorHandler;
20 * Error-Handler for error-messages from the Facebook Graph-API.
22 * This error-handler handels responses withe the HTTP-status code
23 * {@code 400 BAD REQUEST}. It tries to extract and parse the error-message
24 * from the HTTP-body. Successfully extracted and parsed messages are mapped
25 * to a hierarchy of exceptions, that reflects the hierarchy of the error-
28 * If the HTTP-status-code of the response is not {@code 400 BAD REQUEST} or
29 * the HTTP-body could not be extracted or parsed, this error-handler
30 * delegates the handling to its parent.
32 * @see <a href="https://developers.facebook.com/docs/graph-api/using-graph-api/v2.5#errors">Graph-API Documentation</a>
33 * @see <a href="http://fbdevwiki.com/wiki/Error_codes">Inofficial Wiki For Facebook-Developers</a>
36 public class GraphApiErrorResponseErrorHandler implements ResponseErrorHandler
38 private final static Logger LOG =
39 LoggerFactory.getLogger(GraphApiErrorResponseErrorHandler.class);
41 private final ResponseErrorHandler parent;
44 public GraphApiErrorResponseErrorHandler(ResponseErrorHandler errorHandler)
48 ? new DefaultResponseErrorHandler()
54 public boolean hasError(ClientHttpResponse response) throws IOException
57 HttpStatus.Series.CLIENT_ERROR.equals(response.getStatusCode().series())
58 || this.parent.hasError(response);
62 public void handleError(final ClientHttpResponse response) throws IOException
64 GraphApiErrorResponseErrorHandler.handleError(parent, response);
67 public static void handleError(
68 final ResponseErrorHandler parent,
69 final ClientHttpResponse response
74 if (response.getBody() == null)
76 // There is no body to interpret in the HTTP-message
77 LOG.warn("Could not convert the response into an exception, because there is no message-body.");
78 parent.handleError(response);
82 final byte[] body = FileCopyUtils.copyToByteArray(response.getBody());
83 GraphApiException error;
87 error = GraphApiException.create(response.getStatusCode(), response.getHeaders(), body);
88 if (LOG.isInfoEnabled())
89 LOG.info("error-response: {}", new String(body, Charset.forName("UTF-8")));
93 // The body of the HTTP-message could not be parsed.
94 // Let the parent error-handler try to handle the response.
97 "Could not convert the response into an exception, " +
98 "because the body is unparsable: error={}, body={}",
100 new String(body, Charset.forName("UTF-8"))
103 // To do so, we have to wrap the original response to fill in
104 // the buffered body, if needed
105 ClientHttpResponse buffered = new ClientHttpResponse()
108 public HttpStatus getStatusCode() throws IOException
110 return response.getStatusCode();
114 public synchronized InputStream getBody() throws IOException
116 return new ByteArrayInputStream(body);
120 public HttpHeaders getHeaders()
122 return response.getHeaders();
126 public String getStatusText() throws IOException
128 return response.getStatusText();
138 public int getRawStatusCode() throws IOException
140 return response.getRawStatusCode();
144 parent.handleError(buffered);