Java tutorial
/* * Copyright 2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package pl.sgorecki.facebook.marketing.ads.impl; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.http.HttpStatus; import org.springframework.http.client.ClientHttpResponse; import org.springframework.social.*; import org.springframework.social.facebook.api.FacebookError; import org.springframework.web.client.DefaultResponseErrorHandler; import pl.sgorecki.facebook.marketing.ads.InvalidCampaignStatusException; import pl.sgorecki.facebook.marketing.ads.InvalidParameterException; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import static org.springframework.social.facebook.api.FacebookErrors.*; /** * Subclass of {@link DefaultResponseErrorHandler} that handles errors from Facebook's * Graph API, interpreting them into appropriate exceptions. * * @author Craig Walls */ class FacebookAdsErrorHandler extends DefaultResponseErrorHandler { // Rate limiting errors public static final int USER_APP_TOO_MANY_CALLS = 613; // Ad Level Rate Limit error public static final int AD_CREATION_LIMIT_EXCEEDED = 1487225; private static final String FACEBOOK_PROVIDER_ID = "facebook-ads"; private final static Log logger = LogFactory.getLog(FacebookAdsErrorHandler.class); @Override public void handleError(ClientHttpResponse response) throws IOException { FacebookError error = extractErrorFromResponse(response); handleFacebookError(response.getStatusCode(), error); } /** * Examines the error data returned from Facebook and throws the most applicable exception. */ void handleFacebookError(HttpStatus statusCode, FacebookError error) { if (error.getCode() != null) { int code = error.getCode(); if (code == UNKNOWN) { throw new UncategorizedApiException(FACEBOOK_PROVIDER_ID, error.getMessage(), null); } else if (code == SERVICE) { throw new ServerException(FACEBOOK_PROVIDER_ID, error.getMessage()); } else if (code == TOO_MANY_CALLS || code == USER_TOO_MANY_CALLS || code == EDIT_FEED_TOO_MANY_USER_CALLS || code == EDIT_FEED_TOO_MANY_USER_ACTION_CALLS || code == USER_APP_TOO_MANY_CALLS || code == AD_CREATION_LIMIT_EXCEEDED) { throw new RateLimitExceededException(FACEBOOK_PROVIDER_ID); } else if (code == PERMISSION_DENIED || isUserPermissionError(code)) { throw new InsufficientPermissionException(FACEBOOK_PROVIDER_ID); } else if (code == PARAM_SESSION_KEY || code == PARAM_SIGNATURE) { throw new InvalidAuthorizationException(FACEBOOK_PROVIDER_ID, error.getMessage()); } else if (code == PARAM_ACCESS_TOKEN && error.getSubcode() == null) { throw new InvalidAuthorizationException(FACEBOOK_PROVIDER_ID, error.getMessage()); } else if (code == PARAM_ACCESS_TOKEN && error.getSubcode() == 463) { throw new ExpiredAuthorizationException(FACEBOOK_PROVIDER_ID); } else if (code == PARAM_ACCESS_TOKEN) { throw new RevokedAuthorizationException(FACEBOOK_PROVIDER_ID, error.getMessage()); } else if (code == MESG_DUPLICATE) { throw new DuplicateStatusException(FACEBOOK_PROVIDER_ID, error.getMessage()); } else if (code == DATA_OBJECT_NOT_FOUND || code == PATH_UNKNOWN) { throw new ResourceNotFoundException(FACEBOOK_PROVIDER_ID, error.getMessage()); } else if (code == PARAM && error.getSubcode() != null && error.getSubcode() == 1487564) { throw new InvalidCampaignStatusException(FACEBOOK_PROVIDER_ID, error.getUserMessage()); } else if (code == PARAM && error.getSubcode() != null) { throw new InvalidParameterException(FACEBOOK_PROVIDER_ID, error.getUserMessage()); } else { throw new UncategorizedApiException(FACEBOOK_PROVIDER_ID, error.getMessage(), null); } } } private FacebookError extractErrorFromResponse(ClientHttpResponse response) throws IOException { String json = readResponseJson(response); try { ObjectMapper mapper = new ObjectMapper(new JsonFactory()); JsonNode jsonNode = mapper.readValue(json, JsonNode.class); if (jsonNode.has("error")) { JsonNode errorNode = jsonNode.get("error"); Integer code = errorNode.has("code") ? errorNode.get("code").intValue() : null; String type = errorNode.has("type") ? errorNode.get("type").asText() : null; String message = errorNode.has("message") ? errorNode.get("message").asText() : null; Integer subcode = errorNode.has("error_subcode") ? errorNode.get("error_subcode").intValue() : null; String userMessage = errorNode.has("error_user_msg") ? errorNode.get("error_user_msg").asText() : null; String userTitle = errorNode.has("error_user_title") ? errorNode.get("error_user_title").asText() : null; FacebookError error = new FacebookError(code, type, message, subcode, userMessage, userTitle); if (logger.isDebugEnabled()) { logger.debug("Facebook error: "); logger.debug(" CODE : " + error.getCode()); logger.debug(" TYPE : " + error.getType()); logger.debug(" SUBCODE : " + error.getSubcode()); logger.debug(" MESSAGE : " + error.getMessage()); logger.debug(" USER TITLE : " + error.getUserTitle()); logger.debug(" USER MESSAGE: " + error.getUserMessage()); } return error; } } catch (JsonParseException e) { return null; } return null; } private String readResponseJson(ClientHttpResponse response) throws IOException { String json = readFully(response.getBody()); if (logger.isDebugEnabled()) { logger.debug("Error from Facebook: " + json); } return json; } private String readFully(InputStream in) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(in)); StringBuilder sb = new StringBuilder(); while (reader.ready()) { sb.append(reader.readLine()); } return sb.toString(); } }