michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: package org.mozilla.gecko.background.fxa; michael@0: michael@0: import org.mozilla.gecko.R; michael@0: import org.mozilla.gecko.sync.ExtendedJSONObject; michael@0: import org.mozilla.gecko.sync.HTTPFailureException; michael@0: import org.mozilla.gecko.sync.net.SyncStorageResponse; michael@0: michael@0: import ch.boye.httpclientandroidlib.HttpResponse; michael@0: import ch.boye.httpclientandroidlib.HttpStatus; michael@0: michael@0: /** michael@0: * From https://github.com/mozilla/fxa-auth-server/blob/master/docs/api.md. michael@0: */ michael@0: public class FxAccountClientException extends Exception { michael@0: private static final long serialVersionUID = 7953459541558266597L; michael@0: michael@0: public FxAccountClientException(String detailMessage) { michael@0: super(detailMessage); michael@0: } michael@0: michael@0: public FxAccountClientException(Exception e) { michael@0: super(e); michael@0: } michael@0: michael@0: public static class FxAccountClientRemoteException extends FxAccountClientException { michael@0: private static final long serialVersionUID = 2209313149952001097L; michael@0: michael@0: public final HttpResponse response; michael@0: public final long httpStatusCode; michael@0: public final long apiErrorNumber; michael@0: public final String error; michael@0: public final String message; michael@0: public final String info; michael@0: public final ExtendedJSONObject body; michael@0: michael@0: public FxAccountClientRemoteException(HttpResponse response, long httpStatusCode, long apiErrorNumber, String error, String message, String info, ExtendedJSONObject body) { michael@0: super(new HTTPFailureException(new SyncStorageResponse(response))); michael@0: if (body == null) { michael@0: throw new IllegalArgumentException("body must not be null"); michael@0: } michael@0: this.response = response; michael@0: this.httpStatusCode = httpStatusCode; michael@0: this.apiErrorNumber = apiErrorNumber; michael@0: this.error = error; michael@0: this.message = message; michael@0: this.info = info; michael@0: this.body = body; michael@0: } michael@0: michael@0: @Override michael@0: public String toString() { michael@0: return ""; michael@0: } michael@0: michael@0: public boolean isInvalidAuthentication() { michael@0: return httpStatusCode == HttpStatus.SC_UNAUTHORIZED; michael@0: } michael@0: michael@0: public boolean isAccountAlreadyExists() { michael@0: return apiErrorNumber == FxAccountRemoteError.ATTEMPT_TO_CREATE_AN_ACCOUNT_THAT_ALREADY_EXISTS; michael@0: } michael@0: michael@0: public boolean isAccountDoesNotExist() { michael@0: return apiErrorNumber == FxAccountRemoteError.ATTEMPT_TO_ACCESS_AN_ACCOUNT_THAT_DOES_NOT_EXIST; michael@0: } michael@0: michael@0: public boolean isBadPassword() { michael@0: return apiErrorNumber == FxAccountRemoteError.INCORRECT_PASSWORD; michael@0: } michael@0: michael@0: public boolean isUnverified() { michael@0: return apiErrorNumber == FxAccountRemoteError.ATTEMPT_TO_OPERATE_ON_AN_UNVERIFIED_ACCOUNT; michael@0: } michael@0: michael@0: public boolean isUpgradeRequired() { michael@0: return michael@0: apiErrorNumber == FxAccountRemoteError.ENDPOINT_IS_NO_LONGER_SUPPORTED || michael@0: apiErrorNumber == FxAccountRemoteError.INCORRECT_LOGIN_METHOD_FOR_THIS_ACCOUNT || michael@0: apiErrorNumber == FxAccountRemoteError.INCORRECT_KEY_RETRIEVAL_METHOD_FOR_THIS_ACCOUNT || michael@0: apiErrorNumber == FxAccountRemoteError.INCORRECT_API_VERSION_FOR_THIS_ACCOUNT; michael@0: } michael@0: michael@0: public boolean isTooManyRequests() { michael@0: return apiErrorNumber == FxAccountRemoteError.CLIENT_HAS_SENT_TOO_MANY_REQUESTS; michael@0: } michael@0: michael@0: public boolean isServerUnavailable() { michael@0: return apiErrorNumber == FxAccountRemoteError.SERVICE_TEMPORARILY_UNAVAILABLE_DUE_TO_HIGH_LOAD; michael@0: } michael@0: michael@0: public boolean isBadEmailCase() { michael@0: return apiErrorNumber == FxAccountRemoteError.INCORRECT_EMAIL_CASE; michael@0: } michael@0: michael@0: public int getErrorMessageStringResource() { michael@0: if (isUpgradeRequired()) { michael@0: return R.string.fxaccount_remote_error_UPGRADE_REQUIRED; michael@0: } else if (isAccountAlreadyExists()) { michael@0: return R.string.fxaccount_remote_error_ATTEMPT_TO_CREATE_AN_ACCOUNT_THAT_ALREADY_EXISTS; michael@0: } else if (isAccountDoesNotExist()) { michael@0: return R.string.fxaccount_remote_error_ATTEMPT_TO_ACCESS_AN_ACCOUNT_THAT_DOES_NOT_EXIST; michael@0: } else if (isBadPassword()) { michael@0: return R.string.fxaccount_remote_error_INCORRECT_PASSWORD; michael@0: } else if (isUnverified()) { michael@0: return R.string.fxaccount_remote_error_ATTEMPT_TO_OPERATE_ON_AN_UNVERIFIED_ACCOUNT; michael@0: } else if (isTooManyRequests()) { michael@0: return R.string.fxaccount_remote_error_CLIENT_HAS_SENT_TOO_MANY_REQUESTS; michael@0: } else if (isServerUnavailable()) { michael@0: return R.string.fxaccount_remote_error_SERVICE_TEMPORARILY_UNAVAILABLE_TO_DUE_HIGH_LOAD; michael@0: } else { michael@0: return R.string.fxaccount_remote_error_UNKNOWN_ERROR; michael@0: } michael@0: } michael@0: } michael@0: michael@0: public static class FxAccountClientMalformedResponseException extends FxAccountClientRemoteException { michael@0: private static final long serialVersionUID = 2209313149952001098L; michael@0: michael@0: public FxAccountClientMalformedResponseException(HttpResponse response) { michael@0: super(response, 0, FxAccountRemoteError.UNKNOWN_ERROR, "Response malformed", "Response malformed", "Response malformed", new ExtendedJSONObject()); michael@0: } michael@0: } michael@0: }