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: }