// // Copyright (c) 2014 VK.com // // Permission is hereby granted, free of charge, to any person obtaining a copy of // this software and associated documentation files (the "Software"), to deal in // the Software without restriction, including without limitation the rights to // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of // the Software, and to permit persons to whom the Software is furnished to do so, // subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // package com.vk.sdk.api; import android.net.Uri; import com.vk.sdk.VKObject; import com.vk.sdk.util.VKJsonHelper; import org.json.JSONException; import org.json.JSONObject; import java.util.ArrayList; import java.util.Map; /** * Class for presenting VK SDK and VK API errors */ public class VKError extends VKObject { public static final int VK_API_ERROR = -101; /** * @deprecated Use VK_CANCELED instead */ public static final int VK_API_CANCELED = -102; public static final int VK_CANCELED = -102; /** * @deprecated Use VK_REQUEST_NOT_PREPARED instead */ public static final int VK_API_REQUEST_NOT_PREPARED = -103; public static final int VK_REQUEST_NOT_PREPARED = -103; /** * @deprecated Use VK_JSON_FAILED instead */ public static final int VK_API_JSON_FAILED = -104; public static final int VK_JSON_FAILED = -104; /** * @deprecated Use VK_REQUEST_HTTP_FAILED instead */ public static final int VK_API_REQUEST_HTTP_FAILED = -105; public static final int VK_REQUEST_HTTP_FAILED = -105; /** * Contains system HTTP error */ public Exception httpError; /** * Describes API error */ public VKError apiError; /** * Request which caused error */ public VKRequest request; /** * May contains such errors:<br/> * <b>HTTP status code</b> if HTTP error occured;<br/> * <b>VK_API_ERROR</b> if API error occured;<br/> * <b>VK_API_CANCELED</b> if request was canceled;<br/> * <b>VK_API_REQUEST_NOT_PREPARED</b> if error occured while preparing request; */ public int errorCode; /** * API error message */ public String errorMessage; /** * Reason for authorization fail */ public String errorReason; /** * API parameters passed to request */ public ArrayList<Map<String, String>> requestParams; /** * Captcha identifier for captcha-check */ public String captchaSid; /** * Image for captcha-check */ public String captchaImg; /** * Redirection address if validation check required */ public String redirectUri; /** * Generate new error with code * * @param errorCode positive if it's an HTTP error. Negative if it's API or SDK error */ public VKError(int errorCode) { this.errorCode = errorCode; } /** * Generate API error from JSON * * @param json Json description of VK API error */ @SuppressWarnings("unchecked") public VKError(JSONObject json) throws JSONException { VKError internalError = new VKError(json.getInt(VKApiConst.ERROR_CODE)); internalError.errorMessage = json.getString(VKApiConst.ERROR_MSG); internalError.requestParams = (ArrayList<Map<String, String>>) VKJsonHelper.toList( json.getJSONArray(VKApiConst.REQUEST_PARAMS)); if (internalError.errorCode == 14) { internalError.captchaImg = json.getString(VKApiConst.CAPTCHA_IMG); internalError.captchaSid = json.getString(VKApiConst.CAPTCHA_SID); } if (internalError.errorCode == 17) { internalError.redirectUri = json.getString(VKApiConst.REDIRECT_URI); } this.errorCode = VK_API_ERROR; this.apiError = internalError; } private static final String FAIL = "fail"; private static final String ERROR_REASON = "error_reason"; private static final String ERROR_DESCRIPTION = "error_description"; /** * Generate API error from HTTP-query * * @param queryParams key-value parameters */ public VKError(Map<String, String> queryParams) { this.errorCode = VK_API_ERROR; this.errorReason = queryParams.get(ERROR_REASON); this.errorMessage = Uri.decode(queryParams.get(ERROR_DESCRIPTION)); if (queryParams.containsKey(FAIL)) { this.errorReason = "Action failed"; } if (queryParams.containsKey("cancel")) { this.errorCode = VK_CANCELED; this.errorReason = "User canceled request"; } } /** * Repeats failed captcha request with user entered answer to captcha * * @param userEnteredCode answer for captcha */ public void answerCaptcha(String userEnteredCode) { VKParameters params = new VKParameters(); params.put(VKApiConst.CAPTCHA_SID, captchaSid); params.put(VKApiConst.CAPTCHA_KEY, userEnteredCode); request.addExtraParameters(params); request.repeat(); } public static VKError getRegisteredError(long requestId) { return (VKError) getRegisteredObject(requestId); } private void appendFields(StringBuilder builder) { if (errorReason != null) builder.append(String.format("; %s", errorReason)); if (errorMessage != null) builder.append(String.format("; %s", errorMessage)); } @Override public String toString() { StringBuilder errorString = new StringBuilder("VKError ("); switch (this.errorCode) { case VK_API_ERROR: errorString.append("API error"); if (apiError != null) { errorString.append(apiError.toString()); } break; case VK_CANCELED: errorString.append("Canceled"); break; case VK_REQUEST_NOT_PREPARED: errorString.append("Request wasn't prepared"); break; case VK_JSON_FAILED: errorString.append("JSON failed"); break; case VK_REQUEST_HTTP_FAILED: errorString.append("HTTP failed"); break; default: errorString.append(String.format("code: %d; ", errorCode)); break; } appendFields(errorString); errorString.append(")"); return errorString.toString(); } }