diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/RestExceptionResult.java b/scm-webapp/src/main/java/sonia/scm/api/rest/RestExceptionResult.java new file mode 100644 index 0000000000..4a41acf5e8 --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/RestExceptionResult.java @@ -0,0 +1,209 @@ +/** + * Copyright (c) 2010, Sebastian Sdorra All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. 2. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. 3. Neither the name of SCM-Manager; + * nor the names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://bitbucket.org/sdorra/scm-manager + * + */ + + + +package sonia.scm.api.rest; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.common.base.Objects; +import com.google.common.base.Throwables; + +//~--- JDK imports ------------------------------------------------------------ + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * + * @author Sebastian Sdorra + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlRootElement(name = "exception") +public class RestExceptionResult +{ + + /** + * Constructs ... + * + */ + public RestExceptionResult() {} + + /** + * Constructs ... + * + * + * @param throwable + */ + public RestExceptionResult(Throwable throwable) + { + this(throwable.getMessage(), throwable); + } + + /** + * Constructs ... + * + * + * @param message + * @param stacktrace + */ + public RestExceptionResult(String message, String stacktrace) + { + this.message = message; + this.stacktrace = stacktrace; + } + + /** + * Constructs ... + * + * + * @param message + * @param throwable + */ + public RestExceptionResult(String message, Throwable throwable) + { + this(message, Throwables.getStackTraceAsString(throwable)); + } + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @param obj + * + * @return + */ + @Override + public boolean equals(Object obj) + { + if (obj == null) + { + return false; + } + + if (getClass() != obj.getClass()) + { + return false; + } + + final RestExceptionResult other = (RestExceptionResult) obj; + + return Objects.equal(message, other.message) + && Objects.equal(stacktrace, other.stacktrace); + } + + /** + * Method description + * + * + * @return + */ + @Override + public int hashCode() + { + return Objects.hashCode(message, stacktrace); + } + + /** + * Method description + * + * + * @return + */ + @Override + public String toString() + { + //J- + return Objects.toStringHelper(this) + .add("message", message) + .add("stacktrace", stacktrace) + .toString(); + //J+ + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + public String getMessage() + { + return message; + } + + /** + * Method description + * + * + * @return + */ + public String getStacktrace() + { + return stacktrace; + } + + //~--- set methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param message + */ + public void setMessage(String message) + { + this.message = message; + } + + /** + * Method description + * + * + * @param stacktrace + */ + public void setStacktrace(String stacktrace) + { + this.stacktrace = stacktrace; + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private String message; + + /** Field description */ + private String stacktrace; +} diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AbstractManagerResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AbstractManagerResource.java index 89d5e0d0b3..b34066661f 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AbstractManagerResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AbstractManagerResource.java @@ -43,6 +43,7 @@ import org.slf4j.LoggerFactory; import sonia.scm.LastModifiedAware; import sonia.scm.Manager; import sonia.scm.ModelObject; +import sonia.scm.api.rest.RestExceptionResult; import sonia.scm.security.ScmSecurityException; import sonia.scm.util.AssertUtil; import sonia.scm.util.HttpUtil; @@ -59,6 +60,7 @@ import javax.ws.rs.core.EntityTag; import javax.ws.rs.core.GenericEntity; import javax.ws.rs.core.Request; import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; import javax.ws.rs.core.UriInfo; /** @@ -154,12 +156,12 @@ public abstract class AbstractManagerResource + diff --git a/scm-webapp/src/main/webapp/resources/js/action/sonia.action.exceptionwindow.js b/scm-webapp/src/main/webapp/resources/js/action/sonia.action.exceptionwindow.js new file mode 100644 index 0000000000..59a9d89e59 --- /dev/null +++ b/scm-webapp/src/main/webapp/resources/js/action/sonia.action.exceptionwindow.js @@ -0,0 +1,96 @@ +/* * + * Copyright (c) 2010, Sebastian Sdorra + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of SCM-Manager; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://bitbucket.org/sdorra/scm-manager + * + */ + + +Sonia.action.ExceptionWindow = Ext.extend(Ext.Window,{ + + title: null, + message: null, + stacktrace: null, + icon: Ext.MessageBox.ERROR, + + // TODO i18n + // labels + okText: 'Ok', + detailsText: 'Details', + exceptionText: 'Exception', + + initComponent: function(){ + var config = { + title: this.title, + width: 300, + height: 110, + closable: true, + resizable: true, + plain: true, + border: false, + modal: true, + bodyCssClass: 'x-window-dlg', + items: [{ + xtype: 'panel', + height: 45, + bodyCssClass: 'x-panel-mc x-dlg-icon', + html: '
' + this.message + '
' + },{ + id: 'stacktraceArea', + xtype: 'textarea', + editable: false, + fieldLabel: this.exceptionText, + value: this.stacktrace, + width: '98%', + height: 260, + hidden: true + }], + buttons: [{ + text: this.okText, + scope: this, + handler: this.close + },{ + id: 'detailButton', + text: this.detailsText, + scope: this, + handler: this.showDetails + }] + } + + Ext.apply(this, Ext.apply(this.initialConfig, config)); + Sonia.action.ChangePasswordWindow.superclass.initComponent.apply(this, arguments); + }, + + showDetails: function(){ + Ext.getCmp('detailButton').setDisabled(true); + Ext.getCmp('stacktraceArea').setVisible(true); + this.setWidth(640); + this.setHeight(380); + this.center(); + } + +}); \ No newline at end of file diff --git a/scm-webapp/src/main/webapp/resources/js/config/sonia.config.scmconfigpanel.js b/scm-webapp/src/main/webapp/resources/js/config/sonia.config.scmconfigpanel.js index aa49d48aac..78ad33cc14 100644 --- a/scm-webapp/src/main/webapp/resources/js/config/sonia.config.scmconfigpanel.js +++ b/scm-webapp/src/main/webapp/resources/js/config/sonia.config.scmconfigpanel.js @@ -205,8 +205,8 @@ Sonia.config.ScmConfigPanel = Ext.extend(Sonia.config.ConfigPanel,{ }, failure: function(result){ this.el.unmask(); - main.handleFailure( - result.status, + main.handleRestFailure( + result, this.errorTitleText, this.errorMsgText ); @@ -234,8 +234,8 @@ Sonia.config.ScmConfigPanel = Ext.extend(Sonia.config.ConfigPanel,{ failure: function(result){ el.unmask(); clearTimeout(tid); - main.handleFailure( - result.status, + main.handleRestFailure( + result, this.errorTitleText, this.errorMsgText ); diff --git a/scm-webapp/src/main/webapp/resources/js/config/sonia.config.simpleconfigform.js b/scm-webapp/src/main/webapp/resources/js/config/sonia.config.simpleconfigform.js index 54739e9a60..224b722e20 100644 --- a/scm-webapp/src/main/webapp/resources/js/config/sonia.config.simpleconfigform.js +++ b/scm-webapp/src/main/webapp/resources/js/config/sonia.config.simpleconfigform.js @@ -54,8 +54,8 @@ Sonia.config.SimpleConfigForm = Ext.extend(Sonia.config.ConfigForm,{ }, failure: function(result){ this.el.unmask(); - main.handleFailure( - result.status, + main.handleRestFailure( + result, null, this.failedText ); @@ -79,8 +79,8 @@ Sonia.config.SimpleConfigForm = Ext.extend(Sonia.config.ConfigForm,{ failure: function(result){ el.unmask(); clearTimeout(tid); - main.handleFailure( - result.status, + main.handleRestFailure( + result, null, this.failedText ); diff --git a/scm-webapp/src/main/webapp/resources/js/group/sonia.group.formpanel.js b/scm-webapp/src/main/webapp/resources/js/group/sonia.group.formpanel.js index 825d6a33ea..cf754a0945 100644 --- a/scm-webapp/src/main/webapp/resources/js/group/sonia.group.formpanel.js +++ b/scm-webapp/src/main/webapp/resources/js/group/sonia.group.formpanel.js @@ -81,8 +81,8 @@ Sonia.group.FormPanel = Ext.extend(Sonia.rest.FormPanel,{ this.fireEvent('updateFailed', group); clearTimeout(tid); el.unmask(); - main.handleFailure( - result.status, + main.handleRestFailure( + result, this.errorTitleText, this.updateErrorMsgText ); @@ -124,8 +124,8 @@ Sonia.group.FormPanel = Ext.extend(Sonia.rest.FormPanel,{ this.fireEvent('creationFailed', item); clearTimeout(tid); el.unmask(); - main.handleFailure( - result.status, + main.handleRestFailure( + result, this.errorTitleText, this.createErrorMsgText ); diff --git a/scm-webapp/src/main/webapp/resources/js/group/sonia.group.panel.js b/scm-webapp/src/main/webapp/resources/js/group/sonia.group.panel.js index f2971d16a8..af03e43741 100644 --- a/scm-webapp/src/main/webapp/resources/js/group/sonia.group.panel.js +++ b/scm-webapp/src/main/webapp/resources/js/group/sonia.group.panel.js @@ -119,8 +119,8 @@ Sonia.group.Panel = Ext.extend(Sonia.rest.Panel, { this.resetPanel(); }, failure: function(result){ - main.handleFailure( - result.status, + main.handleRestFailure( + result, this.errorTitleText, this.errorMsgText ); diff --git a/scm-webapp/src/main/webapp/resources/js/panel/sonia.panel.syntaxhighlighterpanel.js b/scm-webapp/src/main/webapp/resources/js/panel/sonia.panel.syntaxhighlighterpanel.js index 20cf70d5a8..adb2dfc198 100644 --- a/scm-webapp/src/main/webapp/resources/js/panel/sonia.panel.syntaxhighlighterpanel.js +++ b/scm-webapp/src/main/webapp/resources/js/panel/sonia.panel.syntaxhighlighterpanel.js @@ -214,8 +214,8 @@ Sonia.panel.SyntaxHighlighterPanel = Ext.extend(Ext.Panel, { this.highlight(); }, failure: function(result){ - main.handleFailure( - result.status, + main.handleRestFailure( + result, this.loadErrorTitleText, this.loadErrorMsgText ); diff --git a/scm-webapp/src/main/webapp/resources/js/plugin/sonia.plugin.center.js b/scm-webapp/src/main/webapp/resources/js/plugin/sonia.plugin.center.js index 542ad0a6ba..11113e2601 100644 --- a/scm-webapp/src/main/webapp/resources/js/plugin/sonia.plugin.center.js +++ b/scm-webapp/src/main/webapp/resources/js/plugin/sonia.plugin.center.js @@ -99,8 +99,8 @@ Sonia.plugin.Center = Ext.extend(Ext.util.Observable, { console.debug('plugin installation failed'); } loadingBox.hide(); - main.handleFailure( - result.status, + main.handleRestFailure( + result, this.errorTitleText, this.installFailedText ); @@ -133,8 +133,8 @@ Sonia.plugin.Center = Ext.extend(Ext.util.Observable, { console.debug('plugin uninstallation failed'); } loadingBox.hide(); - main.handleFailure( - result.status, + main.handleRestFailure( + result, this.errorTitleText, this.uninstallFailedText ); @@ -168,8 +168,8 @@ Sonia.plugin.Center = Ext.extend(Ext.util.Observable, { console.debug('plugin update failed'); } loadingBox.hide(); - main.handleFailure( - result.status, + main.handleRestFailure( + result, this.errorTitleText, this.updateFailedText ); diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.commitpanel.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.commitpanel.js index 902bd6f57b..5af2a096d1 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.commitpanel.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.commitpanel.js @@ -120,8 +120,8 @@ Sonia.repository.CommitPanel = Ext.extend(Ext.Panel, { this.update(changeset) }, failure: function(result){ - main.handleFailure( - result.status, + main.handleRestFailure( + result, this.errorTitleText, this.errorMsgText ); diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.formpanel.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.formpanel.js index 936b669e15..5d51db40f9 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.formpanel.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.formpanel.js @@ -148,8 +148,8 @@ Sonia.repository.FormPanel = Ext.extend(Sonia.rest.FormPanel,{ this.fireEvent('creationFailed', item); clearTimeout(tid); el.unmask(); - main.handleFailure( - result.status, + main.handleRestFailure( + result, this.errorTitleText, this.createErrorMsgText ); diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.importwindow.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.importwindow.js index 5ce3a2545a..d3b22637d2 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.importwindow.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.importwindow.js @@ -101,8 +101,8 @@ Sonia.repository.ImportWindow = Ext.extend(Ext.Window,{ this.doLayout(); }, failure: function(result){ - main.handleFailure( - result.status, + main.handleRestFailure( + result, this.errorTitleText, this.errorMsgText ); @@ -218,8 +218,8 @@ Sonia.repository.ImportWindow = Ext.extend(Ext.Window,{ this.appendImported(obj); }, failure: function(result){ - main.handleFailure( - result.status, + main.handleRestFailure( + result, this.errorTitleText, this.errorMsgText ); diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.js index 227bc0df1d..13d1d1af56 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.js @@ -138,8 +138,8 @@ Sonia.repository.get = function(id, callback){ execCallback(Ext.decode(response.responseText)); }, failure: function(result){ - main.handleFailure( - result.status + main.handleRestFailure( + result ); } }); diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.panel.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.panel.js index e6fd526d4a..6cb2c5c728 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.panel.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.panel.js @@ -206,8 +206,8 @@ Sonia.repository.Panel = Ext.extend(Sonia.rest.Panel, { this.resetPanel(); }, failure: function(result){ - main.handleFailure( - result.status, + main.handleRestFailure( + result, this.errorTitleText, this.errorMsgText ); diff --git a/scm-webapp/src/main/webapp/resources/js/rest/sonia.rest.jsonstore.js b/scm-webapp/src/main/webapp/resources/js/rest/sonia.rest.jsonstore.js index 7563927ffb..4227062c9e 100644 --- a/scm-webapp/src/main/webapp/resources/js/rest/sonia.rest.jsonstore.js +++ b/scm-webapp/src/main/webapp/resources/js/rest/sonia.rest.jsonstore.js @@ -51,8 +51,8 @@ Sonia.rest.JsonStore = Ext.extend( Ext.data.JsonStore, { if (debug){ console.debug( 'error during store load, status: ' + status ); } - main.handleFailure( - status, + main.handleRestFailure( + response, this.errorTitleText, this.errorMsgText ); diff --git a/scm-webapp/src/main/webapp/resources/js/sonia.scm.js b/scm-webapp/src/main/webapp/resources/js/sonia.scm.js index 933619ad4d..9faa224c58 100644 --- a/scm-webapp/src/main/webapp/resources/js/sonia.scm.js +++ b/scm-webapp/src/main/webapp/resources/js/sonia.scm.js @@ -65,6 +65,14 @@ Sonia.scm.Main = Ext.extend(Ext.util.Observable, { errorSessionExpiredTitle: 'Session expired', errorSessionExpiredMessage: 'Your session is expired. Please relogin.', + + // TODO i18n + + errorNoPermissionsTitle: 'Not permitted', + errorNoPermissionsMessage: 'You have not enough permissions to execute this action.', + + errorNotFoundTitle: 'Not found', + errorNotFoundMessage: 'The resource could not be found.', mainTabPanel: null, @@ -382,12 +390,17 @@ Sonia.scm.Main = Ext.extend(Ext.util.Observable, { console.debug( "callback is not a function or object. " + callback ); } }, this); - }, + }, - handleFailure: function(status, title, message){ + handleRestFailure: function(response, title, message){ + this.handleFailure(response.status, title, message, response.responseText); + }, + + handleFailure: function(status, title, message, serverException){ if (debug){ console.debug( 'handle failure for status code: ' + status ); } + // TODO handle already exists exceptions specific if ( status == 401 ){ Ext.Msg.show({ title: this.errorSessionExpiredTitle, @@ -400,6 +413,18 @@ Sonia.scm.Main = Ext.extend(Ext.util.Observable, { }, scope: this }); + } else if ( status == 403 ){ + Ext.Msg.show({ + title: this.errorNoPermissionsTitle, + msg: this.errorNoPermissionsMessage, + buttons: Ext.Msg.OKCANCEL + }); + } else if ( status == 404 ){ + Ext.Msg.show({ + title: this.errorNotFoundTitle, + msg: this.errorNotFoundMessage, + buttons: Ext.Msg.OKCANCEL + }); } else { if ( title == null ){ title = this.errorTitle; @@ -407,12 +432,42 @@ Sonia.scm.Main = Ext.extend(Ext.util.Observable, { if ( message == null ){ message = this.errorMessage; } - Ext.MessageBox.show({ - title: title, - msg: String.format(message, status), - buttons: Ext.MessageBox.OK, - icon:Ext.MessageBox.ERROR - }); + + var text = null; + if (serverException){ + try { + if ( Ext.isString(serverException) ){ + serverException = Ext.decode(serverException); + } + text = serverException.stacktrace; + if ( debug ){ + console.debug( text ); + } + } catch (e){ + if ( debug ){ + console.debug(e); + } + } + } + + message = String.format(message, status); + + if ( text == null ){ + + Ext.MessageBox.show({ + title: title, + msg: message, + buttons: Ext.MessageBox.OK, + icon: Ext.MessageBox.ERROR + }); + + } else { + new Sonia.action.ExceptionWindow({ + title: title, + message: message, + stacktrace: text + }).show(); + } } }, diff --git a/scm-webapp/src/main/webapp/resources/js/user/sonia.user.formpanel.js b/scm-webapp/src/main/webapp/resources/js/user/sonia.user.formpanel.js index 580ef9f33d..470e0ab168 100644 --- a/scm-webapp/src/main/webapp/resources/js/user/sonia.user.formpanel.js +++ b/scm-webapp/src/main/webapp/resources/js/user/sonia.user.formpanel.js @@ -134,8 +134,8 @@ Sonia.user.FormPanel = Ext.extend(Sonia.rest.FormPanel,{ this.execCallback(this.onUpdate, item); }, failure: function(result){ - main.handleFailure( - result.status, + main.handleRestFailure( + result, this.errorTitleText, this.updateErrorMsgText ); @@ -165,8 +165,8 @@ Sonia.user.FormPanel = Ext.extend(Sonia.rest.FormPanel,{ this.execCallback(this.onCreate, user); }, failure: function(result){ - main.handleFailure( - result.status, + main.handleRestFailure( + result, this.errorTitleText, this.createErrorMsgText ); diff --git a/scm-webapp/src/main/webapp/resources/js/user/sonia.user.panel.js b/scm-webapp/src/main/webapp/resources/js/user/sonia.user.panel.js index 8801343be3..a3ad2667ed 100644 --- a/scm-webapp/src/main/webapp/resources/js/user/sonia.user.panel.js +++ b/scm-webapp/src/main/webapp/resources/js/user/sonia.user.panel.js @@ -140,8 +140,8 @@ Sonia.user.Panel = Ext.extend(Sonia.rest.Panel, { this.resetPanel(); }, failure: function(result){ - main.handleFailure( - result.status, + main.handleRestFailure( + result, this.errorTitleText, this.errorMsgText );