diff --git a/core/che-core-git-impl-native/src/main/java/org/eclipse/che/git/impl/nativegit/ssh/SshKeyProviderImpl.java b/core/che-core-git-impl-native/src/main/java/org/eclipse/che/git/impl/nativegit/ssh/SshKeyProviderImpl.java index 97189657ab..32fc9b758c 100644 --- a/core/che-core-git-impl-native/src/main/java/org/eclipse/che/git/impl/nativegit/ssh/SshKeyProviderImpl.java +++ b/core/che-core-git-impl-native/src/main/java/org/eclipse/che/git/impl/nativegit/ssh/SshKeyProviderImpl.java @@ -59,13 +59,13 @@ public class SshKeyProviderImpl implements SshKeyProvider { try { pair = sshService.getPair("git", host); } catch (ServerException | NotFoundException e) { - throw new GitException("Unable get private ssh key"); + throw new GitException("Unable get private ssh key", 32068); } // check keys existence String privateKey = pair.getPrivateKey(); if (privateKey == null) { - throw new GitException("Unable get private ssh key"); + throw new GitException("Unable get private ssh key", 32068); } final String publicKey = pair.getPublicKey(); diff --git a/core/commons/che-core-commons-gwt/src/main/java/org/eclipse/che/ide/commons/exception/ServerException.java b/core/commons/che-core-commons-gwt/src/main/java/org/eclipse/che/ide/commons/exception/ServerException.java index 74e4f2c671..b25b4fb961 100644 --- a/core/commons/che-core-commons-gwt/src/main/java/org/eclipse/che/ide/commons/exception/ServerException.java +++ b/core/commons/che-core-commons-gwt/src/main/java/org/eclipse/che/ide/commons/exception/ServerException.java @@ -11,8 +11,13 @@ package org.eclipse.che.ide.commons.exception; import org.eclipse.che.ide.rest.HTTPHeader; + +import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.http.client.Response; +import java.util.HashMap; +import java.util.Map; + /** * @author Vitaliy Gulyy */ @@ -24,12 +29,18 @@ public class ServerException extends Exception { private String message = ""; + private int errorCode; + + private Map attributes = new HashMap<>(); + private boolean errorMessageProvided; public ServerException(Response response) { this.response = response; this.errorMessageProvided = checkErrorMessageProvided(); this.message = getMessageFromJSON(response.getText()); + this.errorCode = getErrorCodeFromJSON(response.getText()); +// parseJsonAttributes(response.getText()); } public ServerException(Response response, String message) { @@ -57,6 +68,15 @@ public class ServerException extends Exception { return response.getText(); } + public int getErrorCode() { + return errorCode; + } + + public Map getAttributes() { + return attributes; + } + + @Override public String toString() { return getMessage(); @@ -70,6 +90,18 @@ public class ServerException extends Exception { } }-*/; + + private native int getErrorCodeFromJSON(String json) /*-{ + try { + var result = JSON.parse(json).errorCode; + if (result) { + return result; + } + } catch (e) { + } + return -1; + }-*/; + public String getHeader(String key) { return response.getHeader(key); } @@ -83,6 +115,18 @@ public class ServerException extends Exception { return false; } +// private native void parseJsonAttributes(String json) /*-{ +// try { +// var attributes = JSON.parse(json).attributes; +// for(var key in attributes) { +// this.@org.eclipse.che.ide.commons.exception.ServerException.attributes::put(Ljava/lang/String;Ljava/lang/String;)(key, attributes[key]); +// } +// +// } catch (e) { +// console.log(e.message, e); +// } +// }-*/; + public boolean isErrorMessageProvided() { return errorMessageProvided; } diff --git a/core/commons/che-core-commons-gwt/src/main/java/org/eclipse/che/ide/commons/exception/UnauthorizedException.java b/core/commons/che-core-commons-gwt/src/main/java/org/eclipse/che/ide/commons/exception/UnauthorizedException.java index 4904d81e6d..5c25fb2323 100644 --- a/core/commons/che-core-commons-gwt/src/main/java/org/eclipse/che/ide/commons/exception/UnauthorizedException.java +++ b/core/commons/che-core-commons-gwt/src/main/java/org/eclipse/che/ide/commons/exception/UnauthorizedException.java @@ -20,22 +20,15 @@ import org.eclipse.che.ide.rest.AsyncRequest; * @author Sergii Leschenko */ @SuppressWarnings("serial") -public class UnauthorizedException extends Exception { - - private Response response; +public class UnauthorizedException extends ServerException { private AsyncRequest request; public UnauthorizedException(Response response, AsyncRequest request) { - super(response.getText()); - this.response = response; + super(response); this.request = request; } - public Response getResponse() { - return response; - } - public AsyncRequest getRequest() { return request; } diff --git a/core/commons/che-core-commons-gwt/src/main/java/org/eclipse/che/ide/json/JsonHelper.java b/core/commons/che-core-commons-gwt/src/main/java/org/eclipse/che/ide/json/JsonHelper.java index 297e53074e..fbc4e1c300 100644 --- a/core/commons/che-core-commons-gwt/src/main/java/org/eclipse/che/ide/json/JsonHelper.java +++ b/core/commons/che-core-commons-gwt/src/main/java/org/eclipse/che/ide/json/JsonHelper.java @@ -17,6 +17,7 @@ import com.google.gwt.json.client.JSONString; import com.google.gwt.json.client.JSONValue; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -77,6 +78,8 @@ public class JsonHelper { return map; } + //TODO: find a way to avoid those util methods here. + /** Returns message or result of it parse if the message is json. */ public static String parseJsonMessage(String parsedMessage) { try { @@ -89,4 +92,28 @@ public class JsonHelper { } } -} \ No newline at end of file + /** Returns message or result of it parse if the message is json. */ + public static Map parseErrorAttributes(String parsedMessage) { + try { + //parsed message + JSONValue message = JSONParser.parseStrict(parsedMessage).isObject().get("attributes"); + return toMap(message.isObject().toString()); + } catch (Exception e) { + //not found json in message + return Collections.emptyMap(); + } + } + + /** Returns message or result of it parse if the message is json. */ + public static int parseErrorCode(String parsedMessage) { + try { + //parsed message + JSONValue message = JSONParser.parseStrict(parsedMessage).isObject().get("errorCode"); + return new Double(message.isNumber().doubleValue()).intValue(); + } catch (Exception e) { + //not found json in message + return -1; + } + } + +} diff --git a/core/commons/che-core-commons-gwt/src/main/java/org/eclipse/che/ide/websocket/rest/exceptions/ServerException.java b/core/commons/che-core-commons-gwt/src/main/java/org/eclipse/che/ide/websocket/rest/exceptions/ServerException.java index ce50c790cb..a8df663d35 100644 --- a/core/commons/che-core-commons-gwt/src/main/java/org/eclipse/che/ide/websocket/rest/exceptions/ServerException.java +++ b/core/commons/che-core-commons-gwt/src/main/java/org/eclipse/che/ide/websocket/rest/exceptions/ServerException.java @@ -10,11 +10,13 @@ *******************************************************************************/ package org.eclipse.che.ide.websocket.rest.exceptions; +import org.eclipse.che.ide.json.JsonHelper; import org.eclipse.che.ide.rest.HTTPHeader; import org.eclipse.che.ide.websocket.Message; import org.eclipse.che.ide.websocket.rest.Pair; import java.util.List; +import java.util.Map; /** * Thrown when there was an any exception was received from the server over WebSocket. @@ -23,20 +25,29 @@ import java.util.List; */ @SuppressWarnings("serial") public class ServerException extends Exception { + private Message response; + private String message; + + private int errorCode; + + + private Map attributes; + private boolean errorMessageProvided; public ServerException(Message response) { this.response = response; + this.message = JsonHelper.parseJsonMessage(response.getBody()); + this.errorCode = JsonHelper.parseErrorCode(response.getBody()); this.errorMessageProvided = checkErrorMessageProvided(); + this.attributes = JsonHelper.parseErrorAttributes(response.getBody()); } @Override public String getMessage() { - if (response.getBody() == null || response.getBody().isEmpty()) - return null; - return response.getBody(); + return message; } public int getHTTPStatus() { @@ -67,4 +78,13 @@ public class ServerException extends Exception { public boolean isErrorMessageProvided() { return errorMessageProvided; } + + public int getErrorCode() { + return errorCode; + } + + public Map getAttributes() { + return attributes; + } + } diff --git a/core/commons/che-core-commons-gwt/src/main/java/org/eclipse/che/ide/websocket/rest/exceptions/UnauthorizedException.java b/core/commons/che-core-commons-gwt/src/main/java/org/eclipse/che/ide/websocket/rest/exceptions/UnauthorizedException.java index a7fd906e9c..18e223470b 100644 --- a/core/commons/che-core-commons-gwt/src/main/java/org/eclipse/che/ide/websocket/rest/exceptions/UnauthorizedException.java +++ b/core/commons/che-core-commons-gwt/src/main/java/org/eclipse/che/ide/websocket/rest/exceptions/UnauthorizedException.java @@ -18,14 +18,11 @@ import org.eclipse.che.ide.websocket.Message; * @author Artem Zatsarynnyi */ @SuppressWarnings("serial") -public class UnauthorizedException extends Exception { - private Message message; +public class UnauthorizedException extends ServerException { public UnauthorizedException(Message message) { - this.message = message; + super(message); } - public int getHTTPStatus() { - return message.getResponseCode(); - } + } \ No newline at end of file diff --git a/core/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/projectimport/ErrorMessageUtils.java b/core/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/projectimport/ErrorMessageUtils.java index 7a50aeacaa..68b664f743 100644 --- a/core/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/projectimport/ErrorMessageUtils.java +++ b/core/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/projectimport/ErrorMessageUtils.java @@ -12,9 +12,13 @@ package org.eclipse.che.ide.projectimport; import org.eclipse.che.api.core.rest.shared.dto.ServiceError; import org.eclipse.che.ide.commons.exception.JobNotFoundException; +import org.eclipse.che.ide.commons.exception.ServerException; import org.eclipse.che.ide.commons.exception.UnauthorizedException; import org.eclipse.che.ide.dto.DtoFactory; +import java.util.Collections; +import java.util.Map; + /** * The class contains business logic which allows define type of error. * @@ -39,12 +43,43 @@ public class ErrorMessageUtils { if (exception instanceof JobNotFoundException) { return "Project import failed"; } else if (exception instanceof UnauthorizedException) { - UnauthorizedException unauthorizedException = (UnauthorizedException)exception; - ServiceError serverError = dtoFactory.createDtoFromJson(unauthorizedException.getResponse().getText(), - ServiceError.class); - return serverError.getMessage(); + return ((UnauthorizedException)exception).getMessage(); } else { return dtoFactory.createDtoFromJson(exception.getMessage(), ServiceError.class).getMessage(); } } + + /** + * Returns error code of the exception if it is of type {@clink ServerException} and has error code set, or -1 otherwise. + * + * @param exception + * passed exception + * @return error code + */ + public static int getErrorCode(Throwable exception) { + if (exception instanceof ServerException) { + return ((ServerException)exception).getErrorCode(); + } else if (exception instanceof org.eclipse.che.ide.websocket.rest.exceptions.ServerException) { + return ((org.eclipse.che.ide.websocket.rest.exceptions.ServerException)exception).getErrorCode(); + } else { + return -1; + } + } + + /** + * Returns attributes of the exception if it is of type {@clink ServerException} and has attributes set, or empty map otherwise. + * + * @param exception + * passed exception + * @return error code + */ + public static Map getAttributes(Throwable exception) { + if (exception instanceof ServerException) { + return ((ServerException)exception).getAttributes(); + } else if (exception instanceof org.eclipse.che.ide.websocket.rest.exceptions.ServerException) { + return ((org.eclipse.che.ide.websocket.rest.exceptions.ServerException)exception).getAttributes(); + } else { + return Collections.emptyMap(); + } + } } diff --git a/core/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/projectimport/wizard/ProjectImporter.java b/core/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/projectimport/wizard/ProjectImporter.java index e60e84c8df..3aae59be77 100644 --- a/core/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/projectimport/wizard/ProjectImporter.java +++ b/core/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/projectimport/wizard/ProjectImporter.java @@ -30,6 +30,7 @@ import org.eclipse.che.ide.api.project.wizard.ImportProjectNotificationSubscribe import org.eclipse.che.ide.api.wizard.Wizard.CompleteCallback; import org.eclipse.che.ide.projectimport.ErrorMessageUtils; import org.eclipse.che.ide.rest.AsyncRequestCallback; +import org.eclipse.che.ide.util.loging.Log; import javax.validation.constraints.NotNull; @@ -99,12 +100,13 @@ public class ProjectImporter extends AbstractImporter { @Override public void apply(PromiseError exception) throws OperationException { subscriber.onFailure(exception.getMessage()); - String errorMessage = ErrorMessageUtils.getErrorMessage(exception.getCause()); - if (errorMessage.equals("Unable get private ssh key")) { + int errorCode = ErrorMessageUtils.getErrorCode(exception.getCause()); + // no ssh key found code. See org.eclipse.che.git.impl.nativegit.ssh.SshKeyProviderImpl. + if (errorCode == 32068) { callback.onFailure(new Exception(localizationConstant.importProjectMessageUnableGetSshKey())); return; } - callback.onFailure(new Exception(errorMessage)); + callback.onFailure(new Exception(exception.getCause().getMessage())); } }); } diff --git a/core/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/projectimport/wizard/ProjectResolver.java b/core/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/projectimport/wizard/ProjectResolver.java index 5bf97d0377..fe7f329aa0 100644 --- a/core/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/projectimport/wizard/ProjectResolver.java +++ b/core/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/projectimport/wizard/ProjectResolver.java @@ -127,8 +127,7 @@ public class ProjectResolver { @Override protected void onFailure(Throwable exception) { projectNotificationSubscriber.onFailure(exception.getMessage()); - String errorMessage = ErrorMessageUtils.getErrorMessage(exception); - callback.onFailure(new Exception(errorMessage)); + callback.onFailure(new Exception(exception.getMessage())); } }); } diff --git a/core/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/projectimport/wizard/ProjectUpdater.java b/core/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/projectimport/wizard/ProjectUpdater.java index 25dbe757e8..036bed8ee8 100644 --- a/core/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/projectimport/wizard/ProjectUpdater.java +++ b/core/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/projectimport/wizard/ProjectUpdater.java @@ -89,8 +89,7 @@ public class ProjectUpdater { @Override protected void onFailure(Throwable exception) { projectNotificationSubscriber.onFailure(exception.getMessage()); - String errorMessage = ErrorMessageUtils.getErrorMessage(exception); - callback.onFailure(new Exception(errorMessage)); + callback.onFailure(new Exception(exception.getMessage())); } }); } diff --git a/core/platform-api/che-core-api-core/src/main/java/org/eclipse/che/api/core/rest/shared/dto/ExtendedError.java b/core/platform-api/che-core-api-core/src/main/java/org/eclipse/che/api/core/rest/shared/dto/ExtendedError.java new file mode 100644 index 0000000000..c3ccb7170b --- /dev/null +++ b/core/platform-api/che-core-api-core/src/main/java/org/eclipse/che/api/core/rest/shared/dto/ExtendedError.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2012-2016 Codenvy, S.A. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Codenvy, S.A. - initial API and implementation + *******************************************************************************/ +package org.eclipse.che.api.core.rest.shared.dto; + +import org.eclipse.che.dto.shared.DTO; + +import java.util.Map; + +/** + * Extended error which contains error code and optional attributes. + * + * @author Max Shaposhnik (mshaposhnik@codenvy.com) + */ +@DTO +public interface ExtendedError extends ServiceError { + + /** + * Get error code. + * + * @return error code + */ + int getErrorCode(); + + /** + * Set error code. + * + * @param errorCode + * error code + */ + void setErrorCode(int errorCode); + + ExtendedError withErrorCode(int errorCode); + + /** + * Get error attributes. + * + * @return attributes of the error if any + */ + Map getAttributes(); + + /** + * Set error attributes. + * + * @param attributes + * error attributes + */ + void setAttributes(Map attributes); + + ExtendedError withAttributes(Map attributes); + + @Override + ExtendedError withMessage(String message); + +} diff --git a/core/platform-api/che-core-api-git/src/main/java/org/eclipse/che/api/git/GitException.java b/core/platform-api/che-core-api-git/src/main/java/org/eclipse/che/api/git/GitException.java index 76c7b2c9bc..693b734caf 100644 --- a/core/platform-api/che-core-api-git/src/main/java/org/eclipse/che/api/git/GitException.java +++ b/core/platform-api/che-core-api-git/src/main/java/org/eclipse/che/api/git/GitException.java @@ -11,6 +11,12 @@ package org.eclipse.che.api.git; import org.eclipse.che.api.core.ServerException; +import org.eclipse.che.api.core.rest.shared.dto.ExtendedError; + +import java.util.Collections; +import java.util.Map; + +import static org.eclipse.che.dto.server.DtoFactory.newDto; /** * @author andrew00x @@ -20,6 +26,15 @@ public class GitException extends ServerException { super(message); } + public GitException(String message, int errorCode, Map attributes) { + super(newDto(ExtendedError.class).withMessage(message).withErrorCode(errorCode).withAttributes(attributes)); + } + + public GitException(String message, int errorCode) { + this(message, errorCode, Collections.emptyMap()); + } + + public GitException(Throwable cause) { super(cause); }