Android Open Source - CCSocialNetwork Facebook Request Error






From Project

Back to project page CCSocialNetwork.

License

The source code is released under:

GNU Lesser General Public License

If you think the Android project CCSocialNetwork listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/**
 * Copyright 2010-present Facebook./*from   w w  w.j a va2 s .  c o  m*/
 *
 * 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 com.facebook;

import com.facebook.android.R;
import com.facebook.internal.Utility;
import org.json.JSONException;
import org.json.JSONObject;

import java.net.HttpURLConnection;

/**
 * This class represents an error that occurred during a Facebook request.
 * <p/>
 * In general, one would call {@link #getCategory()} to determine the type
 * of error that occurred, and act accordingly. The app can also call
 * {@link #getUserActionMessageId()} in order to get the resource id for a
 * string that can be displayed to the user. For more information on error
 * handling, see <a href="https://developers.facebook.com/docs/reference/api/errors/">
 * https://developers.facebook.com/docs/reference/api/errors/</a>
 */
public final class FacebookRequestError {

    /** Represents an invalid or unknown error code from the server. */
    public static final int INVALID_ERROR_CODE = -1;

    /**
     * Indicates that there was no valid HTTP status code returned, indicating
     * that either the error occurred locally, before the request was sent, or
     * that something went wrong with the HTTP connection. Check the exception
     * from {@link #getException()};
     */
    public static final int INVALID_HTTP_STATUS_CODE = -1;

    private static final int INVALID_MESSAGE_ID = 0;

    private static final String CODE_KEY = "code";
    private static final String BODY_KEY = "body";
    private static final String ERROR_KEY = "error";
    private static final String ERROR_TYPE_FIELD_KEY = "type";
    private static final String ERROR_CODE_FIELD_KEY = "code";
    private static final String ERROR_MESSAGE_FIELD_KEY = "message";
    private static final String ERROR_CODE_KEY = "error_code";
    private static final String ERROR_SUB_CODE_KEY = "error_subcode";
    private static final String ERROR_MSG_KEY = "error_msg";
    private static final String ERROR_REASON_KEY = "error_reason";

    private static class Range {
        private final int start, end;

        private Range(int start, int end) {
            this.start = start;
            this.end = end;
        }

        boolean contains(int value) {
            return start <= value && value <= end;
        }
    }

    private static final int EC_UNKNOWN_ERROR = 1;
    private static final int EC_SERVICE_UNAVAILABLE = 2;
    private static final int EC_APP_TOO_MANY_CALLS = 4;
    private static final int EC_USER_TOO_MANY_CALLS = 17;
    private static final int EC_PERMISSION_DENIED = 10;
    private static final int EC_INVALID_SESSION = 102;
    private static final int EC_INVALID_TOKEN = 190;
    private static final Range EC_RANGE_PERMISSION = new Range(200, 299);
    private static final int EC_APP_NOT_INSTALLED = 458;
    private static final int EC_USER_CHECKPOINTED = 459;
    private static final int EC_PASSWORD_CHANGED = 460;
    private static final int EC_EXPIRED = 463;
    private static final int EC_UNCONFIRMED_USER = 464;

    private static final Range HTTP_RANGE_SUCCESS = new Range(200, 299);
    private static final Range HTTP_RANGE_CLIENT_ERROR = new Range(400, 499);
    private static final Range HTTP_RANGE_SERVER_ERROR = new Range(500, 599);

    private final int userActionMessageId;
    private final boolean shouldNotifyUser;
    private final Category category;
    private final int requestStatusCode;
    private final int errorCode;
    private final int subErrorCode;
    private final String errorType;
    private final String errorMessage;
    private final JSONObject requestResult;
    private final JSONObject requestResultBody;
    private final Object batchRequestResult;
    private final HttpURLConnection connection;
    private final FacebookException exception;

    private FacebookRequestError(int requestStatusCode, int errorCode,
            int subErrorCode, String errorType, String errorMessage, JSONObject requestResultBody,
            JSONObject requestResult, Object batchRequestResult, HttpURLConnection connection,
            FacebookException exception) {
        this.requestStatusCode = requestStatusCode;
        this.errorCode = errorCode;
        this.subErrorCode = subErrorCode;
        this.errorType = errorType;
        this.errorMessage = errorMessage;
        this.requestResultBody = requestResultBody;
        this.requestResult = requestResult;
        this.batchRequestResult = batchRequestResult;
        this.connection = connection;

        boolean isLocalException = false;
        if (exception != null) {
            this.exception = exception;
            isLocalException =  true;
        } else {
            this.exception = new FacebookServiceException(this, errorMessage);
        }

        // Initializes the error categories based on the documented error codes as outlined here
        // https://developers.facebook.com/docs/reference/api/errors/
        Category errorCategory = null;
        int messageId = INVALID_MESSAGE_ID;
        boolean shouldNotify = false;
        if (isLocalException) {
            errorCategory = Category.CLIENT;
            messageId = INVALID_MESSAGE_ID;
        } else {
            if (errorCode == EC_UNKNOWN_ERROR || errorCode == EC_SERVICE_UNAVAILABLE) {
                errorCategory = Category.SERVER;
            } else if (errorCode == EC_APP_TOO_MANY_CALLS || errorCode == EC_USER_TOO_MANY_CALLS) {
                errorCategory = Category.THROTTLING;
            } else if (errorCode == EC_PERMISSION_DENIED || EC_RANGE_PERMISSION.contains(errorCode)) {
                errorCategory = Category.PERMISSION;
                messageId = R.string.com_facebook_requesterror_permissions;
            } else if (errorCode == EC_INVALID_SESSION || errorCode == EC_INVALID_TOKEN) {
                if (subErrorCode == EC_USER_CHECKPOINTED || subErrorCode == EC_UNCONFIRMED_USER) {
                    errorCategory = Category.AUTHENTICATION_RETRY;
                    messageId = R.string.com_facebook_requesterror_web_login;
                    shouldNotify = true;
                } else {
                    errorCategory = Category.AUTHENTICATION_REOPEN_SESSION;

                    if ((subErrorCode == EC_APP_NOT_INSTALLED) || (subErrorCode == EC_EXPIRED)) {
                        messageId = R.string.com_facebook_requesterror_relogin;
                    } else if (subErrorCode == EC_PASSWORD_CHANGED) {
                        messageId = R.string.com_facebook_requesterror_password_changed;
                    } else {
                        messageId = R.string.com_facebook_requesterror_reconnect;
                        shouldNotify = true;
                    }
                }
            }

            if (errorCategory == null) {
                if (HTTP_RANGE_CLIENT_ERROR.contains(requestStatusCode)) {
                    errorCategory = Category.BAD_REQUEST;
                } else if (HTTP_RANGE_SERVER_ERROR.contains(requestStatusCode)) {
                    errorCategory = Category.SERVER;
                } else {
                    errorCategory = Category.OTHER;
                }
            }
        }

        this.category = errorCategory;
        this.userActionMessageId = messageId;
        this.shouldNotifyUser = shouldNotify;
    }

    private FacebookRequestError(int requestStatusCode, int errorCode,
            int subErrorCode, String errorType, String errorMessage, JSONObject requestResultBody,
            JSONObject requestResult, Object batchRequestResult, HttpURLConnection connection) {
        this(requestStatusCode, errorCode, subErrorCode, errorType, errorMessage,
                requestResultBody, requestResult, batchRequestResult, connection, null);
    }

    FacebookRequestError(HttpURLConnection connection, Exception exception) {
        this(INVALID_HTTP_STATUS_CODE, INVALID_ERROR_CODE, INVALID_ERROR_CODE,
                null, null, null, null, null, connection,
                (exception instanceof FacebookException) ?
                        (FacebookException) exception : new FacebookException(exception));
    }

    public FacebookRequestError(int errorCode, String errorType, String errorMessage) {
        this(INVALID_HTTP_STATUS_CODE, errorCode, INVALID_ERROR_CODE, errorType, errorMessage,
                null, null, null, null, null);
    }

    /**
     * Returns the resource id for a user-friendly message for the application to
     * present to the user.
     *
     * @return a user-friendly message to present to the user
     */
    public int getUserActionMessageId() {
        return userActionMessageId;
    }

    /**
     * Returns whether direct user action is required to successfully continue with the Facebook
     * operation. If user action is required, apps can also call {@link #getUserActionMessageId()}
     * in order to get a resource id for a message to show the user.
     *
     * @return whether direct user action is required
     */
    public boolean shouldNotifyUser() {
        return shouldNotifyUser;
    }

    /**
     * Returns the category in which the error belongs. Applications can use the category
     * to determine how best to handle the errors (e.g. exponential backoff for retries if
     * being throttled).
     *
     * @return the category in which the error belong
     */
    public Category getCategory() {
        return category;
    }

    /**
     * Returns the HTTP status code for this particular request.
     *
     * @return the HTTP status code for the request
     */
    public int getRequestStatusCode() {
        return requestStatusCode;
    }

    /**
     * Returns the error code returned from Facebook.
     *
     * @return the error code returned from Facebook
     */
    public int getErrorCode() {
        return errorCode;
    }

    /**
     * Returns the sub-error code returned from Facebook.
     *
     * @return the sub-error code returned from Facebook
     */
    public int getSubErrorCode() {
        return subErrorCode;
    }

    /**
     * Returns the type of error as a raw string. This is generally less useful
     * than using the {@link #getCategory()} method, but can provide further details
     * on the error.
     *
     * @return the type of error as a raw string
     */
    public String getErrorType() {
        return errorType;
    }

    /**
     * Returns the error message returned from Facebook.
     *
     * @return the error message returned from Facebook
     */
    public String getErrorMessage() {
        if (errorMessage != null) {
            return errorMessage;
        } else {
            return exception.getLocalizedMessage();
        }
    }

    /**
     * Returns the body portion of the response corresponding to the request from Facebook.
     *
     * @return the body of the response for the request
     */
    public JSONObject getRequestResultBody() {
        return requestResultBody;
    }

    /**
     * Returns the full JSON response for the corresponding request. In a non-batch request,
     * this would be the raw response in the form of a JSON object. In a batch request, this
     * result will contain the body of the response as well as the HTTP headers that pertain
     * to the specific request (in the form of a "headers" JSONArray).
     *
     * @return the full JSON response for the request
     */
    public JSONObject getRequestResult() {
        return requestResult;
    }

    /**
     * Returns the full JSON response for the batch request. If the request was not a batch
     * request, then the result from this method is the same as {@link #getRequestResult()}.
     * In case of a batch request, the result will be a JSONArray where the elements
     * correspond to the requests in the batch. Callers should check the return type against
     * either JSONObject or JSONArray and cast accordingly.
     *
     * @return the full JSON response for the batch
     */
    public Object getBatchRequestResult() {
        return batchRequestResult;
    }

    /**
     * Returns the HTTP connection that was used to make the request.
     *
     * @return the HTTP connection used to make the request
     */
    public HttpURLConnection getConnection() {
        return connection;
    }

    /**
     * Returns the exception associated with this request, if any.
     *
     * @return the exception associated with this request
     */
    public FacebookException getException() {
        return exception;
    }

    @Override
    public String toString() {
        return new StringBuilder("{HttpStatus: ")
                .append(requestStatusCode)
                .append(", errorCode: ")
                .append(errorCode)
                .append(", errorType: ")
                .append(errorType)
                .append(", errorMessage: ")
                .append(errorMessage)
                .append("}")
                .toString();
    }

    static FacebookRequestError checkResponseAndCreateError(JSONObject singleResult,
            Object batchResult, HttpURLConnection connection) {
        try {
            if (singleResult.has(CODE_KEY)) {
                int responseCode = singleResult.getInt(CODE_KEY);
                Object body = Utility.getStringPropertyAsJSON(singleResult, BODY_KEY,
                        Response.NON_JSON_RESPONSE_PROPERTY);

                if (body != null && body instanceof JSONObject) {
                    JSONObject jsonBody = (JSONObject) body;
                    // Does this response represent an error from the service? We might get either an "error"
                    // with several sub-properties, or else one or more top-level fields containing error info.
                    String errorType = null;
                    String errorMessage = null;
                    int errorCode = INVALID_ERROR_CODE;
                    int errorSubCode = INVALID_ERROR_CODE;

                    boolean hasError = false;
                    if (jsonBody.has(ERROR_KEY)) {
                        // We assume the error object is correctly formatted.
                        JSONObject error = (JSONObject) Utility.getStringPropertyAsJSON(jsonBody, ERROR_KEY, null);

                        errorType = error.optString(ERROR_TYPE_FIELD_KEY, null);
                        errorMessage = error.optString(ERROR_MESSAGE_FIELD_KEY, null);
                        errorCode = error.optInt(ERROR_CODE_FIELD_KEY, INVALID_ERROR_CODE);
                        errorSubCode = error.optInt(ERROR_SUB_CODE_KEY, INVALID_ERROR_CODE);
                        hasError = true;
                    } else if (jsonBody.has(ERROR_CODE_KEY) || jsonBody.has(ERROR_MSG_KEY)
                            || jsonBody.has(ERROR_REASON_KEY)) {
                        errorType = jsonBody.optString(ERROR_REASON_KEY, null);
                        errorMessage = jsonBody.optString(ERROR_MSG_KEY, null);
                        errorCode = jsonBody.optInt(ERROR_CODE_KEY, INVALID_ERROR_CODE);
                        errorSubCode = jsonBody.optInt(ERROR_SUB_CODE_KEY, INVALID_ERROR_CODE);
                        hasError = true;
                    }

                    if (hasError) {
                        return new FacebookRequestError(responseCode, errorCode, errorSubCode,
                                errorType, errorMessage, jsonBody, singleResult, batchResult, connection);
                    }
                }

                // If we didn't get error details, but we did get a failure response code, report it.
                if (!HTTP_RANGE_SUCCESS.contains(responseCode)) {
                    return new FacebookRequestError(responseCode, INVALID_ERROR_CODE,
                            INVALID_ERROR_CODE, null, null,
                            singleResult.has(BODY_KEY) ?
                                    (JSONObject) Utility.getStringPropertyAsJSON(
                                            singleResult, BODY_KEY, Response.NON_JSON_RESPONSE_PROPERTY) : null,
                            singleResult, batchResult, connection);
                }
            }
        } catch (JSONException e) {
            // defer the throwing of a JSONException to the graph object proxy
        }
        return null;
    }

    /**
     * An enum that represents the Facebook SDK classification for the error that occurred.
     */
    public enum Category {
        /**
         * Indicates that the error is authentication related, and that the app should retry
         * the request after some user action.
         */
        AUTHENTICATION_RETRY,

        /**
         * Indicates that the error is authentication related, and that the app should close
         * the session and reopen it.
         */
        AUTHENTICATION_REOPEN_SESSION,

        /** Indicates that the error is permission related. */
        PERMISSION,

        /**
         * Indicates that the error implies the server had an unexpected failure or may be
         * temporarily unavailable.
         */
        SERVER,

        /** Indicates that the error results from the server throttling the client. */
        THROTTLING,

        /**
         * Indicates that the error is Facebook-related but cannot be categorized at this time,
         * and is likely newer than the current version of the SDK.
         */
        OTHER,

        /**
         * Indicates that the error is an application error resulting in a bad or malformed
         * request to the server.
         */
        BAD_REQUEST,

        /**
         * Indicates that this is a client-side error. Examples of this can include, but are
         * not limited to, JSON parsing errors or {@link java.io.IOException}s.
         */
        CLIENT
    };

}




Java Source Code List

com.facebook.AccessTokenSource.java
com.facebook.AccessToken.java
com.facebook.AuthorizationClient.java
com.facebook.FacebookAuthorizationException.java
com.facebook.FacebookDialogException.java
com.facebook.FacebookException.java
com.facebook.FacebookGraphObjectException.java
com.facebook.FacebookOperationCanceledException.java
com.facebook.FacebookRequestError.java
com.facebook.FacebookSdkVersion.java
com.facebook.FacebookServiceException.java
com.facebook.GetTokenClient.java
com.facebook.HttpMethod.java
com.facebook.InsightsLogger.java
com.facebook.LegacyHelper.java
com.facebook.LoggingBehavior.java
com.facebook.LoginActivity.java
com.facebook.NativeProtocol.java
com.facebook.NonCachingTokenCachingStrategy.java
com.facebook.RequestAsyncTask.java
com.facebook.RequestBatch.java
com.facebook.Request.java
com.facebook.Response.java
com.facebook.SessionDefaultAudience.java
com.facebook.SessionLoginBehavior.java
com.facebook.SessionState.java
com.facebook.Session.java
com.facebook.Settings.java
com.facebook.SharedPreferencesTokenCachingStrategy.java
com.facebook.TestSession.java
com.facebook.TokenCachingStrategy.java
com.facebook.UiLifecycleHelper.java
com.facebook.android.AsyncFacebookRunner.java
com.facebook.android.DialogError.java
com.facebook.android.FacebookError.java
com.facebook.android.Facebook.java
com.facebook.android.FbDialog.java
com.facebook.android.Util.java
com.facebook.internal.CacheableRequestBatch.java
com.facebook.internal.FileLruCache.java
com.facebook.internal.Logger.java
com.facebook.internal.ServerProtocol.java
com.facebook.internal.SessionAuthorizationType.java
com.facebook.internal.SessionTracker.java
com.facebook.internal.Utility.java
com.facebook.internal.Validate.java
com.facebook.internal.package-info.java
com.facebook.model.GraphLocation.java
com.facebook.model.GraphMultiResult.java
com.facebook.model.GraphObjectList.java
com.facebook.model.GraphObject.java
com.facebook.model.GraphPlace.java
com.facebook.model.GraphUser.java
com.facebook.model.JsonUtil.java
com.facebook.model.OpenGraphAction.java
com.facebook.model.PropertyName.java
com.facebook.widget.FacebookFragment.java
com.facebook.widget.FriendPickerFragment.java
com.facebook.widget.GraphObjectAdapter.java
com.facebook.widget.GraphObjectCursor.java
com.facebook.widget.GraphObjectPagingLoader.java
com.facebook.widget.ImageDownloader.java
com.facebook.widget.ImageRequest.java
com.facebook.widget.ImageResponseCache.java
com.facebook.widget.ImageResponse.java
com.facebook.widget.LoginButton.java
com.facebook.widget.PickerFragment.java
com.facebook.widget.PlacePickerFragment.java
com.facebook.widget.ProfilePictureView.java
com.facebook.widget.SimpleGraphObjectCursor.java
com.facebook.widget.UrlRedirectCache.java
com.facebook.widget.UserSettingsFragment.java
com.facebook.widget.WebDialog.java
com.facebook.widget.WorkQueue.java
org.example.SocialNetwork.CCSocialNetwork.java
org.example.SocialNetwork.EmailSender.java
org.example.SocialNetwork.InternetConnection.java