You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2020/01/21 07:12:46 UTC

[syncope] branch master updated (d9a6419 -> 01a93d7)

This is an automated email from the ASF dual-hosted git repository.

ilgrosso pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/syncope.git.


    from d9a6419  Uprading Wicket-Bootstrap and ANTLR
     new 7b0ba06  [SYNCOPE-1534] Centralize error message reporting into BaseSession#onException
     new 01a93d7  Upgrading JUnit and Spring Boot - also reverting the workaround in 2b7415f19c83b234b3392202e55d3a1dd9bb305e

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../console/panels/GatewayRouteDirectoryPanel.java |  7 +-
 ...AnyDirectoryPanelAdditionalActionsProvider.java | 26 +++---
 .../console/panels/LinkedAccountModalPanel.java    |  7 +-
 .../console/panels/RemediationDirectoryPanel.java  |  6 +-
 .../policies/ProvisioningPolicyModalPanel.java     |  6 +-
 .../client/console/status/ReconTaskPanel.java      |  8 +-
 .../console/topology/TopologyTogglePanel.java      | 27 +++---
 .../wizards/resources/ResourceProvisionPanel.java  | 13 +--
 .../syncope/client/ui/commons/BaseSession.java     | 33 ++++++++
 .../ui/commons/SyncopeUIRequestCycleListener.java  | 21 ++---
 .../markup/html/form/BaseBinaryFieldPanel.java     |  3 +-
 .../client/ui/commons/wizards/AjaxWizard.java      | 18 ++--
 .../ui/commons/wizards/AjaxWizardBuilder.java      |  8 +-
 .../client/console/SyncopeConsoleSession.java      | 32 ++++++++
 .../client/console/commons/AnyDataProvider.java    |  4 +-
 .../notifications/MailTemplateDirectoryPanel.java  |  6 +-
 .../notifications/NotificationDirectoryPanel.java  |  4 +-
 .../console/notifications/TemplateModal.java       |  4 +-
 .../syncope/client/console/pages/BasePage.java     |  2 +-
 .../client/console/pages/MustChangePassword.java   |  5 +-
 .../syncope/client/console/pages/Realms.java       | 12 ++-
 .../client/console/panels/AbstractLogsPanel.java   |  4 +-
 .../console/panels/AccessTokenDirectoryPanel.java  |  4 +-
 .../console/panels/AnyObjectDirectoryPanel.java    |  7 +-
 .../client/console/panels/AnyTypeClassesPanel.java |  6 +-
 .../client/console/panels/AnyTypesPanel.java       |  6 +-
 .../console/panels/ApplicationDirectoryPanel.java  |  4 +-
 .../console/panels/ApplicationModalPanel.java      |  5 +-
 .../panels/DomainAdminCredentialsPanel.java        |  5 +-
 .../console/panels/DomainDirectoryPanel.java       |  4 +-
 .../console/panels/DomainPoolModalPanel.java       |  4 +-
 .../console/panels/DynRealmDirectoryPanel.java     |  4 +-
 .../client/console/panels/DynRealmModalPanel.java  |  4 +-
 .../client/console/panels/GroupDirectoryPanel.java | 13 +--
 .../panels/ImplementationDirectoryPanel.java       |  4 +-
 .../console/panels/ImplementationModalPanel.java   |  5 +-
 .../client/console/panels/ListViewPanel.java       |  4 +-
 .../client/console/panels/MembersTogglePanel.java  |  5 +-
 .../console/panels/ParametersDirectoryPanel.java   |  4 +-
 .../console/panels/PrivilegeDirectoryPanel.java    |  4 +-
 .../console/panels/RelationshipTypesPanel.java     |  7 +-
 .../client/console/panels/RoleDirectoryPanel.java  |  7 +-
 .../client/console/panels/SchemaTypePanel.java     |  3 +-
 .../panels/SecurityQuestionsModalPanel.java        |  4 +-
 .../console/panels/SecurityQuestionsPanel.java     |  4 +-
 .../client/console/panels/StartAtTogglePanel.java  |  6 +-
 .../panels/TypeExtensionDirectoryPanel.java        |  3 +-
 .../client/console/panels/UserDirectoryPanel.java  | 15 ++--
 .../console/policies/PolicyDirectoryPanel.java     |  4 +-
 .../console/policies/PolicyModalPanelBuilder.java  |  5 +-
 .../console/policies/PolicyRuleDirectoryPanel.java |  4 +-
 .../console/reports/ReportDirectoryPanel.java      |  4 +-
 .../reports/ReportTemplateDirectoryPanel.java      |  6 +-
 .../console/reports/ReportletDirectoryPanel.java   |  4 +-
 .../client/console/status/ChangePasswordModal.java |  4 +-
 .../console/tasks/ExecutionsDirectoryPanel.java    |  4 +-
 .../tasks/NotificationTaskDirectoryPanel.java      |  7 +-
 .../tasks/PropagationTaskDirectoryPanel.java       |  7 +-
 .../console/tasks/SchedTaskDirectoryPanel.java     |  4 +-
 .../console/tasks/TaskStartAtTogglePanel.java      |  7 +-
 .../client/console/tasks/TemplatesTogglePanel.java |  5 +-
 .../wicket/markup/html/form/BinaryFieldPanel.java  |  7 +-
 .../client/console/widgets/JobActionPanel.java     |  6 +-
 .../syncope/client/console/widgets/JobWidget.java  | 12 +--
 .../console/wizards/BaseAjaxWizardBuilder.java     |  4 +-
 .../client/console/wizards/WizardMgtPanel.java     | 33 +++++---
 .../console/wizards/any/AnyWizardBuilder.java      |  5 +-
 .../console/SyncopeConsoleApplicationTest.java     | 67 +++++++++++++++
 .../client/enduser/SyncopeEnduserSession.java      | 32 ++++++++
 .../enduser/markup/html/form/BinaryFieldPanel.java |  7 +-
 .../client/enduser/pages/MustChangePassword.java   |  5 +-
 .../enduser/pages/SelfConfirmPasswordReset.java    |  5 +-
 .../client/enduser/panels/SelfPwdResetPanel.java   | 10 +--
 .../enduser/wizards/any/AnyWizardBuilder.java      |  8 +-
 .../syncope/common/lib/SyncopeClientException.java |  1 -
 .../provisioning/api/utils/ExceptionUtils2.java    |  5 +-
 .../console/panels/BpmnProcessDirectoryPanel.java  | 10 +--
 .../client/console/panels/NewBpmnProcess.java      |  5 +-
 .../console/panels/UserRequestDirectoryPanel.java  |  4 +-
 .../panels/UserRequestFormDirectoryPanel.java      |  9 +-
 .../panels/OIDCProvidersDirectoryPanel.java        | 16 ++--
 .../console/wizards/OIDCProviderWizardBuilder.java |  4 +-
 .../client/console/panels/ImportMetadata.java      |  6 +-
 .../console/panels/SAML2IdPsDirectoryPanel.java    | 15 ++--
 .../client/console/panels/SAML2SPPanel.java        |  4 +-
 .../console/wizards/SAML2IdPWizardBuilder.java     |  5 +-
 .../syncope/client/console/pages/SCIMConfPage.java |  4 +-
 .../syncope/fit/console/AbstractConsoleITCase.java |  3 +-
 .../syncope/fit/console/AbstractTypesITCase.java   | 12 ++-
 .../syncope/fit/console/AnyObjectsITCase.java      |  4 +-
 .../syncope/fit/console/AnyTypeClassesITCase.java  | 13 ++-
 .../apache/syncope/fit/console/AnyTypesITCase.java |  9 +-
 .../apache/syncope/fit/console/BatchesITCase.java  |  6 +-
 .../fit/console/DisplayAttributesITCase.java       |  3 +-
 .../apache/syncope/fit/console/GroupsITCase.java   | 10 +--
 .../org/apache/syncope/fit/console/LogsITCase.java |  4 +-
 .../syncope/fit/console/NotificationsITCase.java   |  9 +-
 .../syncope/fit/console/ParametersITCase.java      | 11 ++-
 .../apache/syncope/fit/console/PoliciesITCase.java | 36 ++++----
 .../apache/syncope/fit/console/RealmsITCase.java   | 14 ++--
 .../fit/console/RelationshipTypesITCase.java       |  4 +-
 .../apache/syncope/fit/console/ReportsITCase.java  |  6 +-
 .../apache/syncope/fit/console/RolesITCase.java    |  6 +-
 .../apache/syncope/fit/console/SchemasITCase.java  | 12 +--
 .../fit/console/SecurityQuestionsITCase.java       |  6 +-
 .../apache/syncope/fit/console/TopologyITCase.java | 20 ++---
 .../apache/syncope/fit/console/UsersITCase.java    | 18 ++--
 .../org/apache/syncope/fit/ui/AbstractUITCase.java | 17 ++++
 pom.xml                                            |  4 +-
 .../apache/syncope/sra/SyncopeSRAApplication.java  | 95 ----------------------
 110 files changed, 502 insertions(+), 571 deletions(-)


[syncope] 02/02: Upgrading JUnit and Spring Boot - also reverting the workaround in 2b7415f19c83b234b3392202e55d3a1dd9bb305e

Posted by il...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ilgrosso pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/syncope.git

commit 01a93d722464b52e7dabe9181a46d9d20d413216
Author: Francesco Chicchiriccò <il...@apache.org>
AuthorDate: Tue Jan 21 08:10:40 2020 +0100

    Upgrading JUnit and Spring Boot - also reverting the workaround in 2b7415f19c83b234b3392202e55d3a1dd9bb305e
---
 pom.xml                                            |  4 +-
 .../apache/syncope/sra/SyncopeSRAApplication.java  | 95 ----------------------
 2 files changed, 2 insertions(+), 97 deletions(-)

diff --git a/pom.xml b/pom.xml
index ce90386..394b9c0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -410,7 +410,7 @@ under the License.
 
     <spring.version>5.2.3.RELEASE</spring.version>
     <spring-security.version>5.2.1.RELEASE</spring-security.version>
-    <spring-boot.version>2.2.3.RELEASE</spring-boot.version>
+    <spring-boot.version>2.2.4.RELEASE</spring-boot.version>
     <spring-cloud-gateway.version>2.2.1.RELEASE</spring-cloud-gateway.version>
 
     <openjpa.version>3.1.0</openjpa.version>
@@ -451,7 +451,7 @@ under the License.
 
     <h2.version>1.4.200</h2.version>
 
-    <junit.version>5.5.2</junit.version>
+    <junit.version>5.6.0</junit.version>
     <mockito.version>3.2.4</mockito.version>
 
     <conf.directory>${project.build.directory}/test-classes</conf.directory>
diff --git a/sra/src/main/java/org/apache/syncope/sra/SyncopeSRAApplication.java b/sra/src/main/java/org/apache/syncope/sra/SyncopeSRAApplication.java
index d607fcf..5a2e05e 100644
--- a/sra/src/main/java/org/apache/syncope/sra/SyncopeSRAApplication.java
+++ b/sra/src/main/java/org/apache/syncope/sra/SyncopeSRAApplication.java
@@ -18,19 +18,12 @@
  */
 package org.apache.syncope.sra;
 
-import io.netty.channel.ChannelOption;
-import io.netty.handler.ssl.SslContextBuilder;
-import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
-import java.security.cert.X509Certificate;
 import java.util.Objects;
 import org.apache.syncope.common.lib.types.IdRepoEntitlement;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.actuate.autoconfigure.security.reactive.EndpointRequest;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.cloud.gateway.config.HttpClientProperties;
 import org.springframework.cloud.gateway.route.Route;
 import org.springframework.cloud.gateway.route.RouteLocator;
 import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
@@ -46,12 +39,7 @@ import org.springframework.security.core.userdetails.UserDetails;
 import org.springframework.security.web.server.SecurityWebFilterChain;
 import org.springframework.security.web.server.util.matcher.NegatedServerWebExchangeMatcher;
 import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher;
-import org.springframework.boot.context.properties.PropertyMapper;
-import org.springframework.util.StringUtils;
 import reactor.core.publisher.Flux;
-import reactor.netty.http.client.HttpClient;
-import reactor.netty.resources.ConnectionProvider;
-import reactor.netty.tcp.ProxyProvider;
 
 @PropertySource("classpath:sra.properties")
 @PropertySource(value = "file:${conf.directory}/sra.properties", ignoreResourceNotFound = true)
@@ -59,8 +47,6 @@ import reactor.netty.tcp.ProxyProvider;
 @SpringBootApplication
 public class SyncopeSRAApplication implements EnvironmentAware {
 
-    private static final Logger LOG = LoggerFactory.getLogger(SyncopeSRAApplication.class);
-
     public static void main(final String[] args) {
         SpringApplication.run(SyncopeSRAApplication.class, args);
     }
@@ -99,85 +85,4 @@ public class SyncopeSRAApplication implements EnvironmentAware {
                 build();
         return new MapReactiveUserDetailsService(user);
     }
-
-    /**
-     * Temp work around https://github.com/spring-cloud/spring-cloud-gateway/issues/1532 .
-     *
-     * @param properties Gateway HTTP Client properties
-     * @return Gateway HTTP Client instance
-     */
-    @Bean
-    public HttpClient gatewayHttpClient(final HttpClientProperties properties) {
-        // configure pool resources
-        HttpClientProperties.Pool pool = properties.getPool();
-
-        ConnectionProvider connectionProvider;
-        if (pool.getType() == HttpClientProperties.Pool.PoolType.DISABLED) {
-            connectionProvider = ConnectionProvider.newConnection();
-        } else if (pool.getType() == HttpClientProperties.Pool.PoolType.FIXED) {
-            connectionProvider = ConnectionProvider.fixed(
-                    pool.getName(), pool.getMaxConnections(), pool.getAcquireTimeout(), pool.getMaxIdleTime(), null);
-        } else {
-            connectionProvider = ConnectionProvider.elastic(pool.getName(), pool.getMaxIdleTime(), null);
-        }
-
-        HttpClient httpClient = HttpClient.create(connectionProvider).tcpConfiguration(tcpClient -> {
-            if (properties.getConnectTimeout() != null) {
-                tcpClient = tcpClient.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, properties.getConnectTimeout());
-            }
-
-            // configure proxy if proxy host is set.
-            HttpClientProperties.Proxy proxy = properties.getProxy();
-
-            if (StringUtils.hasText(proxy.getHost())) {
-                tcpClient = tcpClient.proxy(proxySpec -> {
-                    ProxyProvider.Builder builder = proxySpec.type(ProxyProvider.Proxy.HTTP).host(proxy.getHost());
-
-                    PropertyMapper map = PropertyMapper.get();
-
-                    map.from(proxy::getPort).whenNonNull().to(builder::port);
-                    map.from(proxy::getUsername).whenHasText().to(builder::username);
-                    map.from(proxy::getPassword).whenHasText().to(password -> builder.password(s -> password));
-                    map.from(proxy::getNonProxyHostsPattern).whenHasText().to(builder::nonProxyHosts);
-                });
-            }
-            return tcpClient;
-        });
-
-        HttpClientProperties.Ssl ssl = properties.getSsl();
-        if ((ssl.getKeyStore() != null && ssl.getKeyStore().length() > 0)
-                || ssl.getTrustedX509CertificatesForTrustManager().length > 0
-                || ssl.isUseInsecureTrustManager()) {
-
-            httpClient = httpClient.secure(sslContextSpec -> {
-                // configure ssl
-                SslContextBuilder sslContextBuilder = SslContextBuilder.forClient();
-
-                X509Certificate[] trustedX509Certificates = ssl.getTrustedX509CertificatesForTrustManager();
-                if (trustedX509Certificates.length > 0) {
-                    sslContextBuilder = sslContextBuilder.trustManager(trustedX509Certificates);
-                } else if (ssl.isUseInsecureTrustManager()) {
-                    sslContextBuilder = sslContextBuilder.trustManager(InsecureTrustManagerFactory.INSTANCE);
-                }
-
-                try {
-                    sslContextBuilder = sslContextBuilder.keyManager(ssl.getKeyManagerFactory());
-                } catch (Exception e) {
-                    LOG.error("During SSL configuration", e);
-                }
-
-                sslContextSpec.sslContext(sslContextBuilder).
-                        defaultConfiguration(ssl.getDefaultConfigurationType()).
-                        handshakeTimeout(ssl.getHandshakeTimeout()).
-                        closeNotifyFlushTimeout(ssl.getCloseNotifyFlushTimeout()).
-                        closeNotifyReadTimeout(ssl.getCloseNotifyReadTimeout());
-            });
-        }
-
-        if (properties.isWiretap()) {
-            httpClient = httpClient.wiretap(true);
-        }
-
-        return httpClient;
-    }
 }


[syncope] 01/02: [SYNCOPE-1534] Centralize error message reporting into BaseSession#onException

Posted by il...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ilgrosso pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/syncope.git

commit 7b0ba0662520ad41f4cfdbddc0f11313b7e87f62
Author: Francesco Chicchiriccò <il...@apache.org>
AuthorDate: Mon Jan 20 16:10:12 2020 +0100

    [SYNCOPE-1534] Centralize error message reporting into BaseSession#onException
---
 .../console/panels/GatewayRouteDirectoryPanel.java |  7 +--
 ...AnyDirectoryPanelAdditionalActionsProvider.java | 26 +++++----
 .../console/panels/LinkedAccountModalPanel.java    |  7 +--
 .../console/panels/RemediationDirectoryPanel.java  |  6 +-
 .../policies/ProvisioningPolicyModalPanel.java     |  6 +-
 .../client/console/status/ReconTaskPanel.java      |  8 +--
 .../console/topology/TopologyTogglePanel.java      | 27 ++++-----
 .../wizards/resources/ResourceProvisionPanel.java  | 13 ++---
 .../syncope/client/ui/commons/BaseSession.java     | 33 +++++++++++
 .../ui/commons/SyncopeUIRequestCycleListener.java  | 21 +++----
 .../markup/html/form/BaseBinaryFieldPanel.java     |  3 +-
 .../client/ui/commons/wizards/AjaxWizard.java      | 18 +++---
 .../ui/commons/wizards/AjaxWizardBuilder.java      |  8 ++-
 .../client/console/SyncopeConsoleSession.java      | 32 +++++++++++
 .../client/console/commons/AnyDataProvider.java    |  4 +-
 .../notifications/MailTemplateDirectoryPanel.java  |  6 +-
 .../notifications/NotificationDirectoryPanel.java  |  4 +-
 .../console/notifications/TemplateModal.java       |  4 +-
 .../syncope/client/console/pages/BasePage.java     |  2 +-
 .../client/console/pages/MustChangePassword.java   |  5 +-
 .../syncope/client/console/pages/Realms.java       | 12 ++--
 .../client/console/panels/AbstractLogsPanel.java   |  4 +-
 .../console/panels/AccessTokenDirectoryPanel.java  |  4 +-
 .../console/panels/AnyObjectDirectoryPanel.java    |  7 +--
 .../client/console/panels/AnyTypeClassesPanel.java |  6 +-
 .../client/console/panels/AnyTypesPanel.java       |  6 +-
 .../console/panels/ApplicationDirectoryPanel.java  |  4 +-
 .../console/panels/ApplicationModalPanel.java      |  5 +-
 .../panels/DomainAdminCredentialsPanel.java        |  5 +-
 .../console/panels/DomainDirectoryPanel.java       |  4 +-
 .../console/panels/DomainPoolModalPanel.java       |  4 +-
 .../console/panels/DynRealmDirectoryPanel.java     |  4 +-
 .../client/console/panels/DynRealmModalPanel.java  |  4 +-
 .../client/console/panels/GroupDirectoryPanel.java | 13 ++---
 .../panels/ImplementationDirectoryPanel.java       |  4 +-
 .../console/panels/ImplementationModalPanel.java   |  5 +-
 .../client/console/panels/ListViewPanel.java       |  4 +-
 .../client/console/panels/MembersTogglePanel.java  |  5 +-
 .../console/panels/ParametersDirectoryPanel.java   |  4 +-
 .../console/panels/PrivilegeDirectoryPanel.java    |  4 +-
 .../console/panels/RelationshipTypesPanel.java     |  7 +--
 .../client/console/panels/RoleDirectoryPanel.java  |  7 +--
 .../client/console/panels/SchemaTypePanel.java     |  3 +-
 .../panels/SecurityQuestionsModalPanel.java        |  4 +-
 .../console/panels/SecurityQuestionsPanel.java     |  4 +-
 .../client/console/panels/StartAtTogglePanel.java  |  6 +-
 .../panels/TypeExtensionDirectoryPanel.java        |  3 +-
 .../client/console/panels/UserDirectoryPanel.java  | 15 ++---
 .../console/policies/PolicyDirectoryPanel.java     |  4 +-
 .../console/policies/PolicyModalPanelBuilder.java  |  5 +-
 .../console/policies/PolicyRuleDirectoryPanel.java |  4 +-
 .../console/reports/ReportDirectoryPanel.java      |  4 +-
 .../reports/ReportTemplateDirectoryPanel.java      |  6 +-
 .../console/reports/ReportletDirectoryPanel.java   |  4 +-
 .../client/console/status/ChangePasswordModal.java |  4 +-
 .../console/tasks/ExecutionsDirectoryPanel.java    |  4 +-
 .../tasks/NotificationTaskDirectoryPanel.java      |  7 +--
 .../tasks/PropagationTaskDirectoryPanel.java       |  7 +--
 .../console/tasks/SchedTaskDirectoryPanel.java     |  4 +-
 .../console/tasks/TaskStartAtTogglePanel.java      |  7 +--
 .../client/console/tasks/TemplatesTogglePanel.java |  5 +-
 .../wicket/markup/html/form/BinaryFieldPanel.java  |  7 +--
 .../client/console/widgets/JobActionPanel.java     |  6 +-
 .../syncope/client/console/widgets/JobWidget.java  | 12 ++--
 .../console/wizards/BaseAjaxWizardBuilder.java     |  4 +-
 .../client/console/wizards/WizardMgtPanel.java     | 33 +++++++----
 .../console/wizards/any/AnyWizardBuilder.java      |  5 +-
 .../console/SyncopeConsoleApplicationTest.java     | 67 ++++++++++++++++++++++
 .../client/enduser/SyncopeEnduserSession.java      | 32 +++++++++++
 .../enduser/markup/html/form/BinaryFieldPanel.java |  7 +--
 .../client/enduser/pages/MustChangePassword.java   |  5 +-
 .../enduser/pages/SelfConfirmPasswordReset.java    |  5 +-
 .../client/enduser/panels/SelfPwdResetPanel.java   | 10 +---
 .../enduser/wizards/any/AnyWizardBuilder.java      |  8 +--
 .../syncope/common/lib/SyncopeClientException.java |  1 -
 .../provisioning/api/utils/ExceptionUtils2.java    |  5 +-
 .../console/panels/BpmnProcessDirectoryPanel.java  | 10 ++--
 .../client/console/panels/NewBpmnProcess.java      |  5 +-
 .../console/panels/UserRequestDirectoryPanel.java  |  4 +-
 .../panels/UserRequestFormDirectoryPanel.java      |  9 ++-
 .../panels/OIDCProvidersDirectoryPanel.java        | 16 +++---
 .../console/wizards/OIDCProviderWizardBuilder.java |  4 +-
 .../client/console/panels/ImportMetadata.java      |  6 +-
 .../console/panels/SAML2IdPsDirectoryPanel.java    | 15 +++--
 .../client/console/panels/SAML2SPPanel.java        |  4 +-
 .../console/wizards/SAML2IdPWizardBuilder.java     |  5 +-
 .../syncope/client/console/pages/SCIMConfPage.java |  4 +-
 .../syncope/fit/console/AbstractConsoleITCase.java |  3 +-
 .../syncope/fit/console/AbstractTypesITCase.java   | 12 ++--
 .../syncope/fit/console/AnyObjectsITCase.java      |  4 +-
 .../syncope/fit/console/AnyTypeClassesITCase.java  | 13 ++---
 .../apache/syncope/fit/console/AnyTypesITCase.java |  9 ++-
 .../apache/syncope/fit/console/BatchesITCase.java  |  6 +-
 .../fit/console/DisplayAttributesITCase.java       |  3 +-
 .../apache/syncope/fit/console/GroupsITCase.java   | 10 ++--
 .../org/apache/syncope/fit/console/LogsITCase.java |  4 +-
 .../syncope/fit/console/NotificationsITCase.java   |  9 ++-
 .../syncope/fit/console/ParametersITCase.java      | 11 ++--
 .../apache/syncope/fit/console/PoliciesITCase.java | 36 ++++++------
 .../apache/syncope/fit/console/RealmsITCase.java   | 14 ++---
 .../fit/console/RelationshipTypesITCase.java       |  4 +-
 .../apache/syncope/fit/console/ReportsITCase.java  |  6 +-
 .../apache/syncope/fit/console/RolesITCase.java    |  6 +-
 .../apache/syncope/fit/console/SchemasITCase.java  | 12 ++--
 .../fit/console/SecurityQuestionsITCase.java       |  6 +-
 .../apache/syncope/fit/console/TopologyITCase.java | 20 +++----
 .../apache/syncope/fit/console/UsersITCase.java    | 18 +++---
 .../org/apache/syncope/fit/ui/AbstractUITCase.java | 17 ++++++
 108 files changed, 500 insertions(+), 474 deletions(-)

diff --git a/client/am/console/src/main/java/org/apache/syncope/client/console/panels/GatewayRouteDirectoryPanel.java b/client/am/console/src/main/java/org/apache/syncope/client/console/panels/GatewayRouteDirectoryPanel.java
index 0d721c9..cc04fcb 100644
--- a/client/am/console/src/main/java/org/apache/syncope/client/console/panels/GatewayRouteDirectoryPanel.java
+++ b/client/am/console/src/main/java/org/apache/syncope/client/console/panels/GatewayRouteDirectoryPanel.java
@@ -24,7 +24,6 @@ import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
 import org.apache.commons.lang3.SerializationUtils;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.AMConstants;
 import org.apache.syncope.client.console.commons.SortableDataProviderComparator;
@@ -86,8 +85,7 @@ public class GatewayRouteDirectoryPanel
                     target.add(container);
                 } catch (Exception e) {
                     LOG.error("While pushing to SRA", e);
-                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                            ? e.getClass().getName() : e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
@@ -153,8 +151,7 @@ public class GatewayRouteDirectoryPanel
                     target.add(container);
                 } catch (SyncopeClientException e) {
                     LOG.error("While deleting {}", route.getKey(), e);
-                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                            ? e.getClass().getName() : e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMAnyDirectoryPanelAdditionalActionsProvider.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMAnyDirectoryPanelAdditionalActionsProvider.java
index 039e9d8..43eafc3 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMAnyDirectoryPanelAdditionalActionsProvider.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMAnyDirectoryPanelAdditionalActionsProvider.java
@@ -21,6 +21,7 @@ package org.apache.syncope.client.console.commons;
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Optional;
 import java.util.stream.Collectors;
 import org.apache.syncope.client.console.PreferenceManager;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
@@ -76,16 +77,17 @@ public class IdMAnyDirectoryPanelAdditionalActionsProvider implements AnyDirecto
             @Override
             public void onEvent(final IEvent<?> event) {
                 if (event.getPayload() instanceof AjaxWizard.NewItemCancelEvent) {
-                    AjaxRequestTarget target = ((AjaxWizard.NewItemCancelEvent) event.getPayload()).getTarget();
-                    modal.close(target);
+                    ((AjaxWizard.NewItemCancelEvent<?>) event.getPayload()).getTarget().
+                            ifPresent(target -> modal.close(target));
                 } else if (event.getPayload() instanceof AjaxWizard.NewItemFinishEvent) {
                     AjaxWizard.NewItemFinishEvent<?> payload = (AjaxWizard.NewItemFinishEvent) event.getPayload();
-                    AjaxRequestTarget target = payload.getTarget();
+                    Optional<AjaxRequestTarget> target = payload.getTarget();
 
                     SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
-                    ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
-
-                    target.add(container);
+                    if (target.isPresent()) {
+                        ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target.get());
+                        target.get().add(container);
+                    }
 
                     if (payload.getResult() instanceof ArrayList) {
                         modal.setContent(new ResultPage<Serializable>(
@@ -108,12 +110,14 @@ public class IdMAnyDirectoryPanelAdditionalActionsProvider implements AnyDirecto
                                 return new ProvisioningReportsPanel(id, reports, pageRef);
                             }
                         });
-                        target.add(modal.getForm());
+                        target.ifPresent(t -> t.add(modal.getForm()));
                     } else if (Constants.OPERATION_SUCCEEDED.equals(payload.getResult())) {
-                        if (csvDownloadBehavior.hasResponse()) {
-                            csvDownloadBehavior.initiate(target);
-                        }
-                        modal.close(target);
+                        target.ifPresent(t -> {
+                            if (csvDownloadBehavior.hasResponse()) {
+                                csvDownloadBehavior.initiate(target.get());
+                            }
+                            modal.close(t);
+                        });
                     }
                 }
             }
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/LinkedAccountModalPanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/LinkedAccountModalPanel.java
index 1dab13c..f1f1b90 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/LinkedAccountModalPanel.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/LinkedAccountModalPanel.java
@@ -21,7 +21,6 @@ package org.apache.syncope.client.console.panels;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.pages.BasePage;
 import org.apache.syncope.client.console.rest.AnyTypeRestClient;
@@ -187,8 +186,7 @@ public class LinkedAccountModalPanel extends Panel implements ModalPanel {
 
                     } catch (SyncopeClientException e) {
                         LOG.error("While contacting linked account", e);
-                        SyncopeConsoleSession.get().error(
-                                StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
+                        SyncopeConsoleSession.get().onException(e);
                         ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
                     }
 
@@ -268,8 +266,7 @@ public class LinkedAccountModalPanel extends Panel implements ModalPanel {
                         SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
                     } catch (Exception e) {
                         LOG.error("While removing linked account {}", linkedAccountTO.getKey(), e);
-                        SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                                ? e.getClass().getName() : e.getMessage());
+                        SyncopeConsoleSession.get().onException(e);
                     }
 
                     checkAddButton();
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/RemediationDirectoryPanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/RemediationDirectoryPanel.java
index 71ac2eb..e250fa2 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/RemediationDirectoryPanel.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/RemediationDirectoryPanel.java
@@ -158,8 +158,7 @@ public class RemediationDirectoryPanel
                         target.add(container);
                     } catch (SyncopeClientException e) {
                         LOG.error("While performing remediation {}", model.getObject().getKey(), e);
-                        SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                                ? e.getClass().getName() : e.getMessage());
+                        SyncopeConsoleSession.get().onException(e);
                     }
                     ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
                 }
@@ -288,8 +287,7 @@ public class RemediationDirectoryPanel
                     target.add(container);
                 } catch (SyncopeClientException e) {
                     LOG.error("While deleting {}", model.getObject().getKey(), e);
-                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                            ? e.getClass().getName() : e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/policies/ProvisioningPolicyModalPanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/policies/ProvisioningPolicyModalPanel.java
index d30407c..f322c02 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/policies/ProvisioningPolicyModalPanel.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/policies/ProvisioningPolicyModalPanel.java
@@ -166,8 +166,7 @@ public class ProvisioningPolicyModalPanel extends AbstractModalPanel<Provisionin
             this.modal.close(target);
         } catch (Exception e) {
             LOG.error("While creating/updating policy", e);
-            SyncopeConsoleSession.get().error(
-                    StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
+            SyncopeConsoleSession.get().onException(e);
         }
         ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
     }
@@ -382,8 +381,7 @@ public class ProvisioningPolicyModalPanel extends AbstractModalPanel<Provisionin
                 try {
                     this.defaultRuleConf = OBJECT_MAPPER.readValue(impl.getBody(), ruleConfClass);
                 } catch (Exception e) {
-                    LOG.debug("Could not deserialize {} as {}",
-                            impl.getBody(), ruleConfClass.getName());
+                    LOG.debug("Could not deserialize {} as {}", impl.getBody(), ruleConfClass.getName());
                 }
             }
         }
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/status/ReconTaskPanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/status/ReconTaskPanel.java
index dfcd6a9..c385265 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/status/ReconTaskPanel.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/status/ReconTaskPanel.java
@@ -21,7 +21,6 @@ package org.apache.syncope.client.console.status;
 import java.util.Comparator;
 import java.util.List;
 import java.util.stream.Collectors;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.ui.commons.Constants;
 import org.apache.syncope.client.console.pages.BasePage;
@@ -186,11 +185,8 @@ public class ReconTaskPanel extends MultilevelPanel.SecondLevel {
                     SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
                 } catch (Exception e) {
                     LOG.error("While attempting reconciliation using query {} on {}",
-                        reconQuery, form.getModelObject(), e);
-                    SyncopeConsoleSession.get().error(resource + ": "
-                            + (StringUtils.isBlank(e.getMessage())
-                            ? e.getClass().getName()
-                            : StringUtils.abbreviate(StringUtils.normalizeSpace(e.getMessage()), 280)));
+                            reconQuery, form.getModelObject(), e);
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 multiLevelPanelRef.prev(target);
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java
index e5fdd91..736d815 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java
@@ -22,6 +22,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
 import java.io.Serializable;
 import java.text.MessageFormat;
+import java.util.Optional;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.audit.AuditHistoryModal;
@@ -191,8 +192,7 @@ public class TopologyTogglePanel extends TogglePanel<Serializable> {
                     SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
                 } catch (Exception e) {
                     LOG.error("While reloading all connectors", e);
-                    SyncopeConsoleSession.get().error(
-                            StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
@@ -272,8 +272,7 @@ public class TopologyTogglePanel extends TogglePanel<Serializable> {
                     toggle(target, false);
                 } catch (SyncopeClientException e) {
                     LOG.error("While deleting resource {}", node.getKey(), e);
-                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                            ? e.getClass().getName() : e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
@@ -370,8 +369,7 @@ public class TopologyTogglePanel extends TogglePanel<Serializable> {
                             toggle(target, false);
                         } catch (Exception e) {
                             LOG.error("While restoring connector {}", node.getKey(), e);
-                            SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                                    ? e.getClass().getName() : e.getMessage());
+                            SyncopeConsoleSession.get().onException(e);
                         }
                         ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
                     }
@@ -412,8 +410,7 @@ public class TopologyTogglePanel extends TogglePanel<Serializable> {
                     toggle(target, false);
                 } catch (SyncopeClientException e) {
                     LOG.error("While deleting resource {}", node.getKey(), e);
-                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                            ? e.getClass().getName() : e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
@@ -625,8 +622,7 @@ public class TopologyTogglePanel extends TogglePanel<Serializable> {
                             toggle(target, false);
                         } catch (Exception e) {
                             LOG.error("While restoring resource {}", node.getKey(), e);
-                            SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                                    ? e.getClass().getName() : e.getMessage());
+                            SyncopeConsoleSession.get().onException(e);
                         }
                         ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
                     }
@@ -689,8 +685,7 @@ public class TopologyTogglePanel extends TogglePanel<Serializable> {
                     toggle(target, false);
                 } catch (SyncopeClientException e) {
                     LOG.error("While cloning resource {}", node.getKey(), e);
-                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                            ? e.getClass().getName() : e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
@@ -707,13 +702,13 @@ public class TopologyTogglePanel extends TogglePanel<Serializable> {
         super.onEvent(event);
 
         if (event.getPayload() instanceof AjaxWizard.NewItemFinishEvent) {
-            final AjaxWizard.NewItemFinishEvent item = AjaxWizard.NewItemFinishEvent.class.cast(event.getPayload());
+            final AjaxWizard.NewItemFinishEvent<?> item = AjaxWizard.NewItemFinishEvent.class.cast(event.getPayload());
             final Serializable result = item.getResult();
-            final AjaxRequestTarget target = item.getTarget();
-            if (result != null && result instanceof ConnInstanceTO) {
+            final Optional<AjaxRequestTarget> target = item.getTarget();
+            if (result != null && result instanceof ConnInstanceTO && target.isPresent()) {
                 // update Toggle Panel header
                 ConnInstanceTO conn = ConnInstanceTO.class.cast(result);
-                setHeader(target, StringUtils.abbreviate(conn.getDisplayName(), HEADER_FIRST_ABBREVIATION));
+                setHeader(target.get(), StringUtils.abbreviate(conn.getDisplayName(), HEADER_FIRST_ABBREVIATION));
             }
         }
     }
diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel.java
index 3ce6cd4..05f7b4e 100644
--- a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel.java
+++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceProvisionPanel.java
@@ -24,7 +24,6 @@ import java.util.List;
 import java.util.Objects;
 import java.util.Optional;
 import java.util.stream.Collectors;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.ui.commons.Constants;
 import org.apache.syncope.client.console.pages.BasePage;
@@ -158,8 +157,7 @@ public class ResourceProvisionPanel extends AbstractModalPanel<Serializable> {
                                             Model.of(provision))));
                 } catch (SyncopeClientException e) {
                     LOG.error("While contacting resource", e);
-                    SyncopeConsoleSession.get().error(
-                            StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                     ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
                 }
             }
@@ -176,8 +174,7 @@ public class ResourceProvisionPanel extends AbstractModalPanel<Serializable> {
                         } catch (Exception e) {
                             LOG.error("While setting latest sync token for {}/{}",
                                     resourceTO.getKey(), provision.getAnyType(), e);
-                            SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                                    ? e.getClass().getName() : e.getMessage());
+                            SyncopeConsoleSession.get().onException(e);
                         }
                         ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
                     }
@@ -194,8 +191,7 @@ public class ResourceProvisionPanel extends AbstractModalPanel<Serializable> {
                         } catch (Exception e) {
                             LOG.error("While removing sync token for {}/{}",
                                     resourceTO.getKey(), provision.getAnyType(), e);
-                            SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                                    ? e.getClass().getName() : e.getMessage());
+                            SyncopeConsoleSession.get().onException(e);
                         }
                         ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
                     }
@@ -293,8 +289,7 @@ public class ResourceProvisionPanel extends AbstractModalPanel<Serializable> {
             modal.close(target);
         } catch (Exception e) {
             LOG.error("While creating or updating {}", resourceTO, e);
-            SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                    ? e.getClass().getName() : e.getMessage());
+            SyncopeConsoleSession.get().onException(e);
         }
         ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
     }
diff --git a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/BaseSession.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/BaseSession.java
index dd31af8..d9ca499 100644
--- a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/BaseSession.java
+++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/BaseSession.java
@@ -22,6 +22,29 @@ import org.apache.commons.lang3.time.FastDateFormat;
 
 public interface BaseSession {
 
+    enum Error {
+        SESSION_EXPIRED("error.session.expired", "Session expired: please login again"),
+        AUTHORIZATION("error.authorization", "Insufficient access rights when performing the requested operation"),
+        REST("error.rest", "There was an error while contacting the Core server");
+
+        private final String key;
+
+        private final String fallback;
+
+        Error(final String key, final String fallback) {
+            this.key = key;
+            this.fallback = fallback;
+        }
+
+        public String key() {
+            return key;
+        }
+
+        public String fallback() {
+            return fallback;
+        }
+    }
+
     void setDomain(String domain);
 
     String getDomain();
@@ -35,4 +58,14 @@ public interface BaseSession {
     <T> void resetClient(Class<T> service);
 
     FastDateFormat getDateFormat();
+
+    /**
+     * Extract and localize (if translation available) the actual message from the given exception; then, report it
+     * via {@link Session#error(java.io.Serializable)}.
+     *
+     * @see org.apache.syncope.client.lib.RestClientExceptionMapper
+     *
+     * @param e raised exception
+     */
+    void onException(Exception e);
 }
diff --git a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/SyncopeUIRequestCycleListener.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/SyncopeUIRequestCycleListener.java
index 7b14cfc..05cce59 100644
--- a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/SyncopeUIRequestCycleListener.java
+++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/SyncopeUIRequestCycleListener.java
@@ -22,6 +22,7 @@ import java.security.AccessControlException;
 import javax.ws.rs.BadRequestException;
 import javax.ws.rs.ForbiddenException;
 import javax.xml.ws.WebServiceException;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.wicket.authorization.UnauthorizedInstantiationException;
 import org.apache.wicket.core.request.handler.PageProvider;
@@ -40,14 +41,6 @@ public abstract class SyncopeUIRequestCycleListener implements IRequestCycleList
 
     private static final Logger LOG = LoggerFactory.getLogger(SyncopeUIRequestCycleListener.class);
 
-    private static final String PAGE_EXPIRED = "Session expired: please login again";
-
-    private static final String MISSING_AUTHORIZATION = "Missing authorization";
-
-    private static final String MISSING_AUTHORIZATION_CORE = "Missing authorization while contacting Syncope core";
-
-    private static final String REST = "Error while contacting Syncope core";
-
     private static Throwable instanceOf(final Exception e, final Class<? extends Exception> clazz) {
         return clazz.isAssignableFrom(e.getClass())
                 ? e
@@ -67,23 +60,23 @@ public abstract class SyncopeUIRequestCycleListener implements IRequestCycleList
 
         IRequestablePage errorPage;
         if (instanceOf(e, UnauthorizedInstantiationException.class) != null) {
-            errorParameters.add("errorMessage", MISSING_AUTHORIZATION);
+            errorParameters.add("errorMessage", BaseSession.Error.AUTHORIZATION.fallback());
             errorPage = getErrorPage(errorParameters);
         } else if (instanceOf(e, AccessControlException.class) != null) {
-            if (instanceOf(e, AccessControlException.class).getMessage().contains("expired")) {
-                errorParameters.add("errorMessage", PAGE_EXPIRED);
+            if (StringUtils.containsIgnoreCase(instanceOf(e, AccessControlException.class).getMessage(), "expired")) {
+                errorParameters.add("errorMessage", BaseSession.Error.SESSION_EXPIRED.fallback());
             } else {
-                errorParameters.add("errorMessage", MISSING_AUTHORIZATION_CORE);
+                errorParameters.add("errorMessage", BaseSession.Error.AUTHORIZATION.fallback());
             }
             errorPage = getErrorPage(errorParameters);
         } else if (instanceOf(e, PageExpiredException.class) != null || !isSignedIn()) {
-            errorParameters.add("errorMessage", PAGE_EXPIRED);
+            errorParameters.add("errorMessage", BaseSession.Error.SESSION_EXPIRED.fallback());
             errorPage = getErrorPage(errorParameters);
         } else if (instanceOf(e, BadRequestException.class) != null
                 || instanceOf(e, WebServiceException.class) != null
                 || instanceOf(e, SyncopeClientException.class) != null) {
 
-            errorParameters.add("errorMessage", REST);
+            errorParameters.add("errorMessage", BaseSession.Error.REST.fallback());
             errorPage = getErrorPage(errorParameters);
         } else {
             Throwable cause = instanceOf(e, ForbiddenException.class);
diff --git a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/BaseBinaryFieldPanel.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/BaseBinaryFieldPanel.java
index db0240e..b779b14 100644
--- a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/BaseBinaryFieldPanel.java
+++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/BaseBinaryFieldPanel.java
@@ -32,8 +32,7 @@ public abstract class BaseBinaryFieldPanel extends FieldPanel<String> {
         super(id, name, model);
     }
 
-    protected abstract void sendError(String message);
+    protected abstract void sendError(Exception exception);
 
     protected abstract Integer getMaxUploadFileSizeMB();
-
 }
diff --git a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/wizards/AjaxWizard.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/wizards/AjaxWizard.java
index 33bf551..7722af9 100644
--- a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/wizards/AjaxWizard.java
+++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/wizards/AjaxWizard.java
@@ -22,12 +22,12 @@ import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Optional;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.client.ui.commons.Constants;
 import org.apache.wicket.Component;
@@ -159,7 +159,7 @@ public abstract class AjaxWizard<T extends Serializable> extends Wizard
 
     protected abstract void onCancelInternal();
 
-    protected abstract void sendError(String message);
+    protected abstract void sendError(Exception exception);
 
     protected abstract void sendWarning(String message);
 
@@ -188,8 +188,7 @@ public abstract class AjaxWizard<T extends Serializable> extends Wizard
             }
         } catch (Exception e) {
             LOG.warn("Wizard error on cancel", e);
-            sendError(StringUtils.isBlank(e.getMessage())
-                    ? e.getClass().getName() : e.getMessage());
+            sendError(e);
             ((BaseWebPage) pageRef.getPage()).getNotificationPanel().refresh(target);
         }
     }
@@ -214,13 +213,12 @@ public abstract class AjaxWizard<T extends Serializable> extends Wizard
             sendWarning(getString("timeout"));
             ((BaseWebPage) pageRef.getPage()).getNotificationPanel().refresh(target);
         } catch (CaptchaNotMatchingException ce) {
-            LOG.error("Wizard error on finish: captcha not matching");
-            sendError(getString(Constants.CAPTCHA_ERROR));
+            LOG.error("Wizard error on finish: captcha not matching", ce);
+            sendError(new WicketRuntimeException(getString(Constants.CAPTCHA_ERROR)));
             ((BaseWebPage) pageRef.getPage()).getNotificationPanel().refresh(target);
         } catch (Exception e) {
             LOG.error("Wizard error on finish", e);
-            sendError(StringUtils.isBlank(e.getMessage())
-                    ? e.getClass().getName() : e.getMessage());
+            sendError(e);
             ((BaseWebPage) pageRef.getPage()).getNotificationPanel().refresh(target);
         }
     }
@@ -260,8 +258,8 @@ public abstract class AjaxWizard<T extends Serializable> extends Wizard
             return item;
         }
 
-        public AjaxRequestTarget getTarget() {
-            return target;
+        public Optional<AjaxRequestTarget> getTarget() {
+            return Optional.ofNullable(target);
         }
 
         public WizardModalPanel<?> getModalPanel() {
diff --git a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/wizards/AjaxWizardBuilder.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/wizards/AjaxWizardBuilder.java
index 7d92c00..ea517e4 100644
--- a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/wizards/AjaxWizardBuilder.java
+++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/wizards/AjaxWizardBuilder.java
@@ -24,8 +24,10 @@ import java.util.List;
 import java.util.concurrent.Callable;
 import java.util.concurrent.Future;
 import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.client.ui.commons.BaseSession;
 import org.apache.wicket.Component;
 import org.apache.wicket.PageReference;
+import org.apache.wicket.Session;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.extensions.wizard.WizardModel;
 import org.slf4j.Logger;
@@ -123,8 +125,8 @@ public abstract class AjaxWizardBuilder<T extends Serializable> extends Abstract
             }
 
             @Override
-            protected void sendError(final String message) {
-                AjaxWizardBuilder.this.sendError(message);
+            protected void sendError(final Exception exception) {
+                BaseSession.class.cast(Session.get()).onException(exception);
             }
 
             @Override
@@ -155,7 +157,7 @@ public abstract class AjaxWizardBuilder<T extends Serializable> extends Abstract
 
     protected abstract long getMaxWaitTimeInSeconds();
 
-    protected abstract void sendError(String message);
+    protected abstract void sendError(Exception exception);
 
     protected abstract void sendWarning(String message);
 
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java
index 9826ecb..829ea80 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.client.console;
 
+import java.security.AccessControlException;
 import java.text.DateFormat;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -29,12 +30,16 @@ import java.util.Set;
 import java.util.concurrent.Callable;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.Future;
+import java.util.stream.Collectors;
+import javax.ws.rs.BadRequestException;
 import javax.ws.rs.ForbiddenException;
 import javax.ws.rs.core.EntityTag;
 import javax.ws.rs.core.MediaType;
+import javax.xml.ws.WebServiceException;
 import org.apache.commons.collections4.list.SetUniqueList;
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.apache.commons.lang3.time.FastDateFormat;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.cxf.jaxrs.client.WebClient;
@@ -44,6 +49,7 @@ import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
 import org.apache.syncope.client.lib.batch.BatchRequest;
 import org.apache.syncope.client.ui.commons.BaseSession;
 import org.apache.syncope.client.ui.commons.Constants;
+import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.info.PlatformInfo;
 import org.apache.syncope.common.lib.info.SystemInfo;
@@ -110,6 +116,32 @@ public class SyncopeConsoleSession extends AuthenticatedWebSession implements Ba
         executor.initialize();
     }
 
+    @Override
+    public void onException(final Exception e) {
+        Throwable root = ExceptionUtils.getRootCause(e);
+        String message = root.getMessage();
+
+        if (root instanceof SyncopeClientException) {
+            SyncopeClientException sce = (SyncopeClientException) root;
+            if (!sce.isComposite()) {
+                message = sce.getElements().stream().collect(Collectors.joining(", "));
+            }
+        } else if (root instanceof AccessControlException || root instanceof ForbiddenException) {
+            Error error = StringUtils.containsIgnoreCase(message, "expired")
+                    ? Error.SESSION_EXPIRED
+                    : Error.AUTHORIZATION;
+            message = getApplication().getResourceSettings().getLocalizer().
+                    getString(error.key(), null, null, null, null, error.fallback());
+        } else if (root instanceof BadRequestException || root instanceof WebServiceException) {
+            message = getApplication().getResourceSettings().getLocalizer().
+                    getString(Error.REST.key(), null, null, null, null, Error.REST.fallback());
+        }
+
+        message = getApplication().getResourceSettings().getLocalizer().
+                getString(message, null, null, null, null, message);
+        error(message);
+    }
+
     public MediaType getMediaType() {
         return clientFactory.getContentType().getMediaType();
     }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/AnyDataProvider.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/AnyDataProvider.java
index 61a723d..f8e6899 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/AnyDataProvider.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/AnyDataProvider.java
@@ -109,7 +109,7 @@ public class AnyDataProvider<A extends AnyTO> extends DirectoryDataProvider<A> {
             }
         } catch (Exception e) {
             LOG.error("While searching with FIQL {}", fiql, e);
-            SyncopeConsoleSession.get().error(e.getMessage());
+            SyncopeConsoleSession.get().onException(e);
 
             Optional<AjaxRequestTarget> target = RequestCycle.get().find(AjaxRequestTarget.class);
             target.ifPresent(ajaxRequestTarget ->
@@ -132,7 +132,7 @@ public class AnyDataProvider<A extends AnyTO> extends DirectoryDataProvider<A> {
             }
         } catch (Exception e) {
             LOG.error("While requesting for size() with FIQL {}", fiql, e);
-            SyncopeConsoleSession.get().error(e.getMessage());
+            SyncopeConsoleSession.get().onException(e);
 
             Optional<AjaxRequestTarget> target = RequestCycle.get().find(AjaxRequestTarget.class);
             target.ifPresent(ajaxRequestTarget ->
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/notifications/MailTemplateDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/notifications/MailTemplateDirectoryPanel.java
index fd283a7..1040109 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/notifications/MailTemplateDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/notifications/MailTemplateDirectoryPanel.java
@@ -167,8 +167,7 @@ public class MailTemplateDirectoryPanel
                     target.add(container);
                 } catch (SyncopeClientException e) {
                     LOG.error("While deleting object {}", model.getObject().getKey(), e);
-                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage()) ? e.getClass().
-                            getName() : e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
@@ -257,8 +256,7 @@ public class MailTemplateDirectoryPanel
                     modal.close(target);
                 } catch (Exception e) {
                     LOG.error("While updating template for {}", content.getKey(), e);
-                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                            ? e.getClass().getName() : e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                 }
             }
             ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/notifications/NotificationDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/notifications/NotificationDirectoryPanel.java
index 2290a67..b61df0f 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/notifications/NotificationDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/notifications/NotificationDirectoryPanel.java
@@ -23,7 +23,6 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.ui.commons.DirectoryDataProvider;
 import org.apache.syncope.client.console.commons.IdRepoConstants;
@@ -141,8 +140,7 @@ public class NotificationDirectoryPanel
                     target.add(container);
                 } catch (SyncopeClientException e) {
                     LOG.error("While deleting object {}", model.getObject().getKey(), e);
-                    SyncopeConsoleSession.get().error(
-                            StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/notifications/TemplateModal.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/notifications/TemplateModal.java
index 4b145f9..3cee48d 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/notifications/TemplateModal.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/notifications/TemplateModal.java
@@ -18,7 +18,6 @@
  */
 package org.apache.syncope.client.console.notifications;
 
-import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.pages.BasePage;
 import org.apache.syncope.client.console.panels.AbstractModalPanel;
@@ -70,8 +69,7 @@ public class TemplateModal<T extends EntityTO, F> extends AbstractModalPanel<T>
             modal.close(target);
         } catch (SyncopeClientException e) {
             LOG.error("While creating template for {}", templateTO.getKey(), e);
-            SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                    ? e.getClass().getName() : e.getMessage());
+            SyncopeConsoleSession.get().onException(e);
         }
         ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
     }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java
index 0654fb4..324769b 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java
@@ -133,7 +133,7 @@ public class BasePage extends BaseWebPage {
 
                     getRequestCycle().scheduleRequestHandlerAfterCurrent(rsrh);
                 } catch (Exception e) {
-                    SyncopeConsoleSession.get().error(getString(Constants.ERROR) + ": " + e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                 }
             }
         };
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/MustChangePassword.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/MustChangePassword.java
index e387f18..a25a1ca 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/MustChangePassword.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/MustChangePassword.java
@@ -18,7 +18,6 @@
  */
 package org.apache.syncope.client.console.pages;
 
-import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.rest.UserSelfRestClient;
 import org.apache.syncope.client.ui.commons.pages.AbstractMustChangePassword;
@@ -45,8 +44,7 @@ public class MustChangePassword extends AbstractMustChangePassword {
         } catch (Exception e) {
             LOG.error("While changing password for {}",
                     SyncopeConsoleSession.get().getSelfTO().getUsername(), e);
-            SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                    ? e.getClass().getName() : e.getMessage());
+            SyncopeConsoleSession.get().onException(e);
             notificationPanel.refresh(target);
         }
     }
@@ -60,5 +58,4 @@ public class MustChangePassword extends AbstractMustChangePassword {
     protected void doCancel() {
         setResponsePage(Login.class);
     }
-
 }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java
index 189b765..48de67d 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java
@@ -157,14 +157,18 @@ public class Realms extends BasePage {
                 final IModel<Serializable> model = new CompoundPropertyModel<>(modalPanel.getItem());
                 templateModal.setFormModel(model);
                 templateModal.header(newItemEvent.getResourceModel());
-                newItemEvent.getTarget().add(templateModal.setContent(modalPanel));
+                newItemEvent.getTarget().ifPresent(t -> t.add(templateModal.setContent(modalPanel)));
                 templateModal.show(true);
             } else if (event.getPayload() instanceof AjaxWizard.NewItemCancelEvent) {
-                templateModal.close(newItemEvent.getTarget());
+                if (newItemEvent.getTarget().isPresent()) {
+                    templateModal.close(newItemEvent.getTarget().get());
+                }
             } else if (event.getPayload() instanceof AjaxWizard.NewItemFinishEvent) {
                 SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
-                ((BaseWebPage) getPage()).getNotificationPanel().refresh(newItemEvent.getTarget());
-                templateModal.close(newItemEvent.getTarget());
+                if (newItemEvent.getTarget().isPresent()) {
+                    ((BasePage) getPage()).getNotificationPanel().refresh(newItemEvent.getTarget().get());
+                    templateModal.close(newItemEvent.getTarget().get());
+                }
             }
         }
     }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AbstractLogsPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AbstractLogsPanel.java
index 0c01695..f37a58c 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AbstractLogsPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AbstractLogsPanel.java
@@ -20,7 +20,6 @@ package org.apache.syncope.client.console.panels;
 
 import java.io.Serializable;
 import java.util.List;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.ui.commons.Constants;
 import org.apache.syncope.client.console.pages.BasePage;
@@ -87,8 +86,7 @@ public abstract class AbstractLogsPanel<T extends Serializable> extends Panel {
                                 target.add(loggerTOs);
                             } catch (SyncopeClientException e) {
                                 LOG.error("Error updating the logger level", e);
-                                SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage()) ? e.getClass().
-                                        getName() : e.getMessage());
+                                SyncopeConsoleSession.get().onException(e);
                             }
                             ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
                         }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AccessTokenDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AccessTokenDirectoryPanel.java
index 074464e..2b7bf74 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AccessTokenDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AccessTokenDirectoryPanel.java
@@ -24,7 +24,6 @@ import java.util.Collection;
 import java.util.Date;
 import java.util.Iterator;
 import java.util.List;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.cxf.rs.security.jose.jws.JwsJwtCompactConsumer;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.ui.commons.Constants;
@@ -127,8 +126,7 @@ public class AccessTokenDirectoryPanel
                     target.add(container);
                 } catch (SyncopeClientException e) {
                     LOG.error("While deleting object {}", model.getObject().getKey(), e);
-                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage()) ? e.getClass().
-                            getName() : e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel.java
index ca0c406..dc1c488 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel.java
@@ -21,7 +21,6 @@ package org.apache.syncope.client.console.panels;
 import java.io.Serializable;
 import java.util.List;
 import org.apache.commons.lang3.SerializationUtils;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeWebApplication;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.IdRepoConstants;
@@ -187,8 +186,7 @@ public class AnyObjectDirectoryPanel extends AnyDirectoryPanel<AnyObjectTO, AnyO
                             target.add(container);
                         } catch (Exception e) {
                             LOG.error("While restoring any object {}", model.getObject().getKey(), e);
-                            SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                                    ? e.getClass().getName() : e.getMessage());
+                            SyncopeConsoleSession.get().onException(e);
                         }
                         ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
                     }
@@ -232,8 +230,7 @@ public class AnyObjectDirectoryPanel extends AnyDirectoryPanel<AnyObjectTO, AnyO
                     target.add(container);
                 } catch (SyncopeClientException e) {
                     LOG.error("While deleting any object {}", model.getObject().getKey(), e);
-                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                            ? e.getClass().getName() : e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AnyTypeClassesPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AnyTypeClassesPanel.java
index 29f2937..b47fc0f 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AnyTypeClassesPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AnyTypeClassesPanel.java
@@ -86,8 +86,7 @@ public class AnyTypeClassesPanel extends TypesDirectoryPanel<
                             modal.close(target);
                         } catch (Exception e) {
                             LOG.error("While creating or updating AnyTypeClassTO", e);
-                            SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage()) ? e.getClass().
-                                    getName() : e.getMessage());
+                            SyncopeConsoleSession.get().onException(e);
                         }
                         ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
                     }
@@ -182,8 +181,7 @@ public class AnyTypeClassesPanel extends TypesDirectoryPanel<
                     target.add(container);
                 } catch (Exception e) {
                     LOG.error("While deleting {}", model.getObject(), e);
-                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                            ? e.getClass().getName() : e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AnyTypesPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AnyTypesPanel.java
index 9cfd12f..965ae9e 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AnyTypesPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AnyTypesPanel.java
@@ -86,8 +86,7 @@ public class AnyTypesPanel extends TypesDirectoryPanel<AnyTypeTO, AnyTypesPanel.
                             modal.close(target);
                         } catch (Exception e) {
                             LOG.error("While creating or updating {}", modelObject, e);
-                            SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage()) ? e.getClass().
-                                    getName() : e.getMessage());
+                            SyncopeConsoleSession.get().onException(e);
                         }
                         ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
                     }
@@ -182,8 +181,7 @@ public class AnyTypesPanel extends TypesDirectoryPanel<AnyTypeTO, AnyTypesPanel.
                     target.add(container);
                 } catch (Exception e) {
                     LOG.error("While deleting {}", model.getObject(), e);
-                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                            ? e.getClass().getName() : e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ApplicationDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ApplicationDirectoryPanel.java
index dcad92f..9a531b4 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ApplicationDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ApplicationDirectoryPanel.java
@@ -24,7 +24,6 @@ import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
 import java.util.stream.Collectors;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.ui.commons.Constants;
 import org.apache.syncope.client.ui.commons.DirectoryDataProvider;
@@ -200,8 +199,7 @@ public class ApplicationDirectoryPanel extends
                     target.add(container);
                 } catch (SyncopeClientException e) {
                     LOG.error("While deleting application {}", model.getObject().getKey(), e);
-                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                            ? e.getClass().getName() : e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ApplicationModalPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ApplicationModalPanel.java
index 9e4953c..6eecac1 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ApplicationModalPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ApplicationModalPanel.java
@@ -18,7 +18,6 @@
  */
 package org.apache.syncope.client.console.panels;
 
-import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.ui.commons.Constants;
 import org.apache.syncope.client.console.pages.BasePage;
@@ -81,10 +80,8 @@ public class ApplicationModalPanel extends AbstractModalPanel<ApplicationTO> {
             this.modal.close(target);
         } catch (Exception e) {
             LOG.error("While creating/updating application", e);
-            SyncopeConsoleSession.get().error(
-                    StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
+            SyncopeConsoleSession.get().onException(e);
         }
         ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
     }
-
 }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DomainAdminCredentialsPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DomainAdminCredentialsPanel.java
index 2d879ed..36d0810 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DomainAdminCredentialsPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DomainAdminCredentialsPanel.java
@@ -19,8 +19,6 @@
 package org.apache.syncope.client.console.panels;
 
 import java.util.List;
-
-import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.pages.BasePage;
 import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
@@ -78,8 +76,7 @@ public class DomainAdminCredentialsPanel extends AbstractModalPanel<Domain> {
             this.modal.close(target);
         } catch (Exception e) {
             LOG.error("While updating domain", e);
-            SyncopeConsoleSession.get().error(
-                    StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
+            SyncopeConsoleSession.get().onException(e);
         }
         ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
     }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DomainDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DomainDirectoryPanel.java
index 6f206ad..f3a399a 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DomainDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DomainDirectoryPanel.java
@@ -23,7 +23,6 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.ui.commons.DirectoryDataProvider;
 import org.apache.syncope.client.console.commons.IdRepoConstants;
@@ -141,8 +140,7 @@ public class DomainDirectoryPanel extends DirectoryPanel<Domain, Domain, DomainP
                     target.add(container);
                 } catch (KeymasterException e) {
                     LOG.error("While deleting {}", domain.getKey(), e);
-                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                            ? e.getClass().getName() : e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DomainPoolModalPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DomainPoolModalPanel.java
index ab6d303..db13629 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DomainPoolModalPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DomainPoolModalPanel.java
@@ -18,7 +18,6 @@
  */
 package org.apache.syncope.client.console.panels;
 
-import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.pages.BasePage;
 import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
@@ -70,8 +69,7 @@ public class DomainPoolModalPanel extends AbstractModalPanel<Domain> {
             this.modal.close(target);
         } catch (Exception e) {
             LOG.error("While updating domain", e);
-            SyncopeConsoleSession.get().error(
-                    StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
+            SyncopeConsoleSession.get().onException(e);
         }
         ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
     }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DynRealmDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DynRealmDirectoryPanel.java
index b38d0cc..3a243a0 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DynRealmDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DynRealmDirectoryPanel.java
@@ -23,7 +23,6 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.ui.commons.Constants;
 import org.apache.syncope.client.ui.commons.DirectoryDataProvider;
@@ -146,8 +145,7 @@ public class DynRealmDirectoryPanel extends
                     target.add(container);
                 } catch (SyncopeClientException e) {
                     LOG.error("While deleting dynamic realm {}", model.getObject().getKey(), e);
-                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                            ? e.getClass().getName() : e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DynRealmModalPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DynRealmModalPanel.java
index b027087..ef4e4f3 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DynRealmModalPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DynRealmModalPanel.java
@@ -140,10 +140,8 @@ public class DynRealmModalPanel extends AbstractModalPanel<DynRealmWrapper> {
             this.modal.close(target);
         } catch (Exception e) {
             LOG.error("While creating/updating dynamic realm", e);
-            SyncopeConsoleSession.get().error(
-                    StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
+            SyncopeConsoleSession.get().onException(e);
         }
         ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
     }
-
 }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/GroupDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/GroupDirectoryPanel.java
index a978417..afdc217 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/GroupDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/GroupDirectoryPanel.java
@@ -22,7 +22,6 @@ import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
 import java.io.Serializable;
 import java.util.List;
 import org.apache.commons.lang3.SerializationUtils;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.SyncopeWebApplication;
@@ -266,8 +265,7 @@ public class GroupDirectoryPanel extends AnyDirectoryPanel<GroupTO, GroupRestCli
                     target.add(container);
                 } catch (SyncopeClientException e) {
                     LOG.error("While provisioning members of group {}", model.getObject().getKey(), e);
-                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                            ? e.getClass().getName() : e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
@@ -287,8 +285,7 @@ public class GroupDirectoryPanel extends AnyDirectoryPanel<GroupTO, GroupRestCli
                     target.add(container);
                 } catch (SyncopeClientException e) {
                     LOG.error("While provisioning members of group {}", model.getObject().getKey(), e);
-                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                            ? e.getClass().getName() : e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
@@ -359,8 +356,7 @@ public class GroupDirectoryPanel extends AnyDirectoryPanel<GroupTO, GroupRestCli
                             target.add(container);
                         } catch (Exception e) {
                             LOG.error("While restoring group {}", model.getObject().getKey(), e);
-                            SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                                    ? e.getClass().getName() : e.getMessage());
+                            SyncopeConsoleSession.get().onException(e);
                         }
                         ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
                     }
@@ -405,8 +401,7 @@ public class GroupDirectoryPanel extends AnyDirectoryPanel<GroupTO, GroupRestCli
                     target.add(container);
                 } catch (SyncopeClientException e) {
                     LOG.error("While deleting group {}", model.getObject().getKey(), e);
-                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                            ? e.getClass().getName() : e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ImplementationDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ImplementationDirectoryPanel.java
index b5006c5..197886a 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ImplementationDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ImplementationDirectoryPanel.java
@@ -23,7 +23,6 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.ui.commons.Constants;
 import org.apache.syncope.client.ui.commons.DirectoryDataProvider;
@@ -165,8 +164,7 @@ public class ImplementationDirectoryPanel extends DirectoryPanel<
                     target.add(container);
                 } catch (SyncopeClientException e) {
                     LOG.error("While deleting object {}", model.getObject().getKey(), e);
-                    SyncopeConsoleSession.get().error(
-                            StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ImplementationModalPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ImplementationModalPanel.java
index 667af62..9615ac5 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ImplementationModalPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ImplementationModalPanel.java
@@ -193,11 +193,8 @@ public class ImplementationModalPanel extends AbstractModalPanel<ImplementationT
             SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
         } catch (Exception e) {
             LOG.error("While creating or updating Implementation", e);
-            SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                    ? e.getClass().getName()
-                    : e.getMessage());
+            SyncopeConsoleSession.get().onException(e);
         }
         ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
     }
-
 }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java
index b646d69..5395b39 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java
@@ -461,7 +461,7 @@ public abstract class ListViewPanel<T extends Serializable> extends WizardMgtPan
     public void onEvent(final IEvent<?> event) {
         if (event.getPayload() instanceof AjaxWizard.NewItemEvent) {
             final T item = ((AjaxWizard.NewItemEvent<T>) event.getPayload()).getItem();
-            final AjaxRequestTarget target = ((AjaxWizard.NewItemEvent<T>) event.getPayload()).getTarget();
+            final Optional<AjaxRequestTarget> target = ((AjaxWizard.NewItemEvent<T>) event.getPayload()).getTarget();
 
             if (event.getPayload() instanceof AjaxWizard.NewItemFinishEvent) {
                 final T old = getActualItem(item, ListViewPanel.this.listOfItems);
@@ -473,7 +473,7 @@ public abstract class ListViewPanel<T extends Serializable> extends WizardMgtPan
                 ListViewPanel.this.listOfItems.add(indexOf, item);
             }
 
-            target.add(ListViewPanel.this);
+            target.ifPresent(t -> t.add(ListViewPanel.this));
             super.onEvent(event);
         } else if (event.getPayload() instanceof ListViewPanel.ListViewReload) {
             final ListViewPanel.ListViewReload<?> payload = (ListViewPanel.ListViewReload<?>) event.getPayload();
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/MembersTogglePanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/MembersTogglePanel.java
index 685b130..c20adb7 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/MembersTogglePanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/MembersTogglePanel.java
@@ -21,7 +21,6 @@ package org.apache.syncope.client.console.panels;
 import java.io.Serializable;
 import java.util.List;
 import java.util.stream.Collectors;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.pages.BasePage;
 import org.apache.syncope.client.console.rest.AnyTypeRestClient;
@@ -83,10 +82,8 @@ public abstract class MembersTogglePanel extends TogglePanel<Serializable> {
                     onApplyInternal(groupTO, typeModel.getObject(), target);
                     toggle(target, false);
                 } catch (SyncopeClientException e) {
-                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                            ? e.getClass().getName()
-                            : e.getMessage());
                     LOG.error("While inspecting group memebers of type {}", typeModel.getObject(), e);
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ParametersDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ParametersDirectoryPanel.java
index 8c691de..c9986eb 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ParametersDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/ParametersDirectoryPanel.java
@@ -25,7 +25,6 @@ import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import java.util.stream.Collectors;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.ui.commons.Constants;
 import org.apache.syncope.client.ui.commons.DirectoryDataProvider;
@@ -169,8 +168,7 @@ public class ParametersDirectoryPanel
                     target.add(container);
                 } catch (Exception e) {
                     LOG.error("While deleting {}", model.getObject(), e);
-                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                            ? e.getClass().getName() : e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/PrivilegeDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/PrivilegeDirectoryPanel.java
index 6c19ef5..3269e06 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/PrivilegeDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/PrivilegeDirectoryPanel.java
@@ -22,7 +22,6 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.ui.commons.Constants;
 import org.apache.syncope.client.ui.commons.DirectoryDataProvider;
@@ -120,8 +119,7 @@ public class PrivilegeDirectoryPanel extends DirectoryPanel<
                     customActionOnFinishCallback(target);
                 } catch (SyncopeClientException e) {
                     LOG.error("While deleting {}", model.getObject().getKey(), e);
-                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                            ? e.getClass().getName() : e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/RelationshipTypesPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/RelationshipTypesPanel.java
index 9a7b8b8..5e4fb5c 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/RelationshipTypesPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/RelationshipTypesPanel.java
@@ -89,8 +89,7 @@ public class RelationshipTypesPanel extends TypesDirectoryPanel<
                             modal.close(target);
                         } catch (Exception e) {
                             LOG.error("While creating or updating {}", modelObject, e);
-                            SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage()) ? e.getClass().
-                                    getName() : e.getMessage());
+                            SyncopeConsoleSession.get().onException(e);
                         }
                         ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
                     }
@@ -184,8 +183,7 @@ public class RelationshipTypesPanel extends TypesDirectoryPanel<
                     target.add(container);
                 } catch (Exception e) {
                     LOG.error("While deleting {}", model.getObject(), e);
-                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                            ? e.getClass().getName() : e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
@@ -222,5 +220,4 @@ public class RelationshipTypesPanel extends TypesDirectoryPanel<
             return new CompoundPropertyModel<>(object);
         }
     }
-
 }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/RoleDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/RoleDirectoryPanel.java
index 7793f07..4c709e5 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/RoleDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/RoleDirectoryPanel.java
@@ -26,7 +26,6 @@ import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import org.apache.commons.lang3.SerializationUtils;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.ui.commons.Constants;
 import org.apache.syncope.client.ui.commons.DirectoryDataProvider;
@@ -230,8 +229,7 @@ public class RoleDirectoryPanel extends DirectoryPanel<RoleTO, RoleWrapper, Role
                             modal.close(target);
                         } catch (Exception e) {
                             LOG.error("While updating console layout for role {}", wrapper.getKey(), e);
-                            SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                                    ? e.getClass().getName() : e.getMessage());
+                            SyncopeConsoleSession.get().onException(e);
                         }
                         ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
                     }
@@ -252,8 +250,7 @@ public class RoleDirectoryPanel extends DirectoryPanel<RoleTO, RoleWrapper, Role
                     target.add(container);
                 } catch (SyncopeClientException e) {
                     LOG.error("While deleting object {}", model.getObject().getKey(), e);
-                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage()) ? e.getClass().
-                            getName() : e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/SchemaTypePanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/SchemaTypePanel.java
index f67d3ba..9954e47 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/SchemaTypePanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/SchemaTypePanel.java
@@ -187,8 +187,7 @@ public class SchemaTypePanel extends TypesDirectoryPanel<SchemaTO, SchemaProvide
                     target.add(container);
                 } catch (Exception e) {
                     LOG.error("While deleting {}", model.getObject(), e);
-                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                            ? e.getClass().getName() : e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/SecurityQuestionsModalPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/SecurityQuestionsModalPanel.java
index 124b5f8..eb5506d 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/SecurityQuestionsModalPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/SecurityQuestionsModalPanel.java
@@ -18,7 +18,6 @@
  */
 package org.apache.syncope.client.console.panels;
 
-import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.ui.commons.Constants;
 import org.apache.syncope.client.console.pages.BasePage;
@@ -62,8 +61,7 @@ public class SecurityQuestionsModalPanel extends AbstractModalPanel<SecurityQues
             modal.close(target);
         } catch (Exception e) {
             LOG.error("While creating or updating {}", securityQuestionTO, e);
-            SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                    ? e.getClass().getName() : e.getMessage());
+            SyncopeConsoleSession.get().onException(e);
         }
         ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
     }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/SecurityQuestionsPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/SecurityQuestionsPanel.java
index dd5a091..d8ae36f 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/SecurityQuestionsPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/SecurityQuestionsPanel.java
@@ -23,7 +23,6 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.ui.commons.Constants;
 import org.apache.syncope.client.ui.commons.DirectoryDataProvider;
@@ -162,8 +161,7 @@ public class SecurityQuestionsPanel extends DirectoryPanel<
                     target.add(container);
                 } catch (Exception e) {
                     LOG.error("While deleting {}", model.getObject(), e);
-                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                            ? e.getClass().getName() : e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/StartAtTogglePanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/StartAtTogglePanel.java
index c0e20ef..6fe131f 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/StartAtTogglePanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/StartAtTogglePanel.java
@@ -20,7 +20,6 @@ package org.apache.syncope.client.console.panels;
 
 import java.io.Serializable;
 import java.util.Date;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.time.FastDateFormat;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.ui.commons.Constants;
@@ -55,7 +54,7 @@ public abstract class StartAtTogglePanel extends TogglePanel<Serializable> {
         addInnerObject(form);
 
         final AjaxDateTimeFieldPanel startAtDate = new AjaxDateTimeFieldPanel(
-                "startAtDate", "startAtDate", startAtDateModel, 
+                "startAtDate", "startAtDate", startAtDateModel,
                 FastDateFormat.getInstance(SyncopeConstants.DATE_PATTERNS[3]));
 
         startAtDate.setReadOnly(true).hideLabel();
@@ -88,9 +87,8 @@ public abstract class StartAtTogglePanel extends TogglePanel<Serializable> {
                     toggle(target, false);
                     target.add(container);
                 } catch (SyncopeClientException e) {
-                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                            ? e.getClass().getName() : e.getMessage());
                     LOG.error("While running task {}", key, e);
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/TypeExtensionDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/TypeExtensionDirectoryPanel.java
index 5c1bcc6..bb306f5 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/TypeExtensionDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/TypeExtensionDirectoryPanel.java
@@ -99,8 +99,7 @@ public class TypeExtensionDirectoryPanel
             SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
         } catch (Exception e) {
             LOG.error("Group update failure", e);
-            SyncopeConsoleSession.get().error(getString(Constants.ERROR) + ": " + e.getMessage());
-
+            SyncopeConsoleSession.get().onException(e);
         }
         ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
     }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/UserDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/UserDirectoryPanel.java
index 9dd6a8d..2b528ef 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/UserDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/UserDirectoryPanel.java
@@ -23,7 +23,6 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 import org.apache.commons.lang3.SerializationUtils;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeWebApplication;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.IdRepoConstants;
@@ -165,8 +164,7 @@ public class UserDirectoryPanel extends AnyDirectoryPanel<UserTO, UserRestClient
                     target.add(container);
                 } catch (Exception e) {
                     LOG.error("While actioning object {}", model.getObject().getKey(), e);
-                    SyncopeConsoleSession.get().error(
-                            StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
@@ -214,8 +212,7 @@ public class UserDirectoryPanel extends AnyDirectoryPanel<UserTO, UserRestClient
                             target.add(container);
                         } catch (Exception e) {
                             LOG.error("While actioning object {}", model.getObject().getKey(), e);
-                            SyncopeConsoleSession.get().error(
-                                    StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
+                            SyncopeConsoleSession.get().onException(e);
                         }
                         ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
                     }
@@ -297,8 +294,7 @@ public class UserDirectoryPanel extends AnyDirectoryPanel<UserTO, UserRestClient
                             target.add(container);
                         } catch (Exception e) {
                             LOG.error("While restoring user {}", model.getObject().getKey(), e);
-                            SyncopeConsoleSession.get().error(
-                                    StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
+                            SyncopeConsoleSession.get().onException(e);
                         }
                         ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
                     }
@@ -344,9 +340,8 @@ public class UserDirectoryPanel extends AnyDirectoryPanel<UserTO, UserRestClient
                     SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
                     target.add(container);
                 } catch (Exception e) {
-                    LOG.error("While deleting object {}", model.getObject().getKey(), e);
-                    SyncopeConsoleSession.get().error(
-                            StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
+                    LOG.error("While deleting user {}", model.getObject().getKey(), e);
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/policies/PolicyDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/policies/PolicyDirectoryPanel.java
index c429d7e..17416a1 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/policies/PolicyDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/policies/PolicyDirectoryPanel.java
@@ -25,7 +25,6 @@ import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import org.apache.commons.lang3.SerializationUtils;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.ui.commons.Constants;
 import org.apache.syncope.client.ui.commons.DirectoryDataProvider;
@@ -178,8 +177,7 @@ public abstract class PolicyDirectoryPanel<T extends PolicyTO>
                     target.add(container);
                 } catch (SyncopeClientException e) {
                     LOG.error("While deleting {}", policyTO.getKey(), e);
-                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                            ? e.getClass().getName() : e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/policies/PolicyModalPanelBuilder.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/policies/PolicyModalPanelBuilder.java
index 4a29eaa..a3d817f 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/policies/PolicyModalPanelBuilder.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/policies/PolicyModalPanelBuilder.java
@@ -21,7 +21,6 @@ package org.apache.syncope.client.console.policies;
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeWebApplication;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.ui.commons.Constants;
@@ -164,11 +163,9 @@ public class PolicyModalPanelBuilder<T extends PolicyTO> extends AbstractModalPa
                 Profile.this.modal.close(target);
             } catch (Exception e) {
                 LOG.error("While creating/updating policy", e);
-                SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                        ? e.getClass().getName() : e.getMessage());
+                SyncopeConsoleSession.get().onException(e);
             }
             ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
         }
     }
-
 }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/policies/PolicyRuleDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/policies/PolicyRuleDirectoryPanel.java
index b5be0bd..b896ec0 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/policies/PolicyRuleDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/policies/PolicyRuleDirectoryPanel.java
@@ -24,7 +24,6 @@ import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
 import java.util.stream.Collectors;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.ui.commons.Constants;
 import org.apache.syncope.client.ui.commons.DirectoryDataProvider;
@@ -173,8 +172,7 @@ public class PolicyRuleDirectoryPanel<T extends PolicyTO> extends DirectoryPanel
                     }
                 } catch (SyncopeClientException e) {
                     LOG.error("While deleting {}", rule.getName(), e);
-                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                            ? e.getClass().getName() : e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/reports/ReportDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/reports/ReportDirectoryPanel.java
index c8b09cf..204687f 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/reports/ReportDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/reports/ReportDirectoryPanel.java
@@ -24,7 +24,6 @@ import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
 import org.apache.commons.lang3.SerializationUtils;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.ui.commons.Constants;
 import org.apache.syncope.client.ui.commons.DirectoryDataProvider;
@@ -251,8 +250,7 @@ public abstract class ReportDirectoryPanel
                     target.add(container);
                 } catch (SyncopeClientException e) {
                     LOG.error("While deleting {}", reportTO.getKey(), e);
-                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                            ? e.getClass().getName() : e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/reports/ReportTemplateDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/reports/ReportTemplateDirectoryPanel.java
index 03eec32..28d7cae 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/reports/ReportTemplateDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/reports/ReportTemplateDirectoryPanel.java
@@ -186,8 +186,7 @@ public class ReportTemplateDirectoryPanel
                     target.add(container);
                 } catch (SyncopeClientException e) {
                     LOG.error("While deleting object {}", model.getObject().getKey(), e);
-                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage()) ? e.getClass().
-                            getName() : e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
@@ -269,8 +268,7 @@ public class ReportTemplateDirectoryPanel
                     modal.close(target);
                 } catch (Exception e) {
                     LOG.error("While updating template for {}", content.getKey(), e);
-                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                            ? e.getClass().getName() : e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                 }
             }
             ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/reports/ReportletDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/reports/ReportletDirectoryPanel.java
index f806afb..a22f865 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/reports/ReportletDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/reports/ReportletDirectoryPanel.java
@@ -25,7 +25,6 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Objects;
 import java.util.stream.Collectors;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.ui.commons.Constants;
 import org.apache.syncope.client.ui.commons.DirectoryDataProvider;
@@ -160,8 +159,7 @@ public class ReportletDirectoryPanel extends DirectoryPanel<
                     customActionOnFinishCallback(target);
                 } catch (SyncopeClientException e) {
                     LOG.error("While deleting {}", reportlet.getName(), e);
-                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                            ? e.getClass().getName() : e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/status/ChangePasswordModal.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/status/ChangePasswordModal.java
index 801073c..e93ab10 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/status/ChangePasswordModal.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/status/ChangePasswordModal.java
@@ -98,9 +98,7 @@ public class ChangePasswordModal extends AbstractModalPanel<AnyWrapper<UserTO>>
             }
         } catch (Exception e) {
             LOG.error("While updating password for user {}", inner, e);
-            SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                    ? e.getClass().getName()
-                    : e.getMessage());
+            SyncopeConsoleSession.get().onException(e);
         }
         super.onSubmit(target);
     }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel.java
index 8514a34..d22e34a 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel.java
@@ -134,8 +134,8 @@ public abstract class ExecutionsDirectoryPanel
                     restClient.deleteExecution(taskExecutionTO.getKey());
                     SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
                     target.add(container);
-                } catch (SyncopeClientException scce) {
-                    SyncopeConsoleSession.get().error(scce.getMessage());
+                } catch (SyncopeClientException e) {
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/NotificationTaskDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/NotificationTaskDirectoryPanel.java
index a9775e3..4b66688 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/NotificationTaskDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/NotificationTaskDirectoryPanel.java
@@ -22,7 +22,6 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.IdRepoConstants;
 import org.apache.syncope.client.console.rest.TaskRestClient;
@@ -147,9 +146,8 @@ public abstract class NotificationTaskDirectoryPanel
                     SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
                     target.add(container);
                 } catch (SyncopeClientException e) {
-                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                            ? e.getClass().getName() : e.getMessage());
                     LOG.error("While running {}", taskTO.getKey(), e);
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
@@ -167,8 +165,7 @@ public abstract class NotificationTaskDirectoryPanel
                     target.add(container);
                 } catch (SyncopeClientException e) {
                     LOG.error("While deleting {}", taskTO.getKey(), e);
-                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                            ? e.getClass().getName() : e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/PropagationTaskDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/PropagationTaskDirectoryPanel.java
index 71cd42c..192227b 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/PropagationTaskDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/PropagationTaskDirectoryPanel.java
@@ -22,7 +22,6 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.IdRepoConstants;
 import org.apache.syncope.client.console.rest.TaskRestClient;
@@ -153,9 +152,8 @@ public abstract class PropagationTaskDirectoryPanel
                     SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
                     target.add(container);
                 } catch (SyncopeClientException e) {
-                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                            ? e.getClass().getName() : e.getMessage());
                     LOG.error("While running {}", taskTO.getKey(), e);
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
@@ -174,8 +172,7 @@ public abstract class PropagationTaskDirectoryPanel
                     PropagationTaskDirectoryPanel.this.getTogglePanel().close(target);
                 } catch (SyncopeClientException e) {
                     LOG.error("While deleting {}", taskTO.getKey(), e);
-                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                            ? e.getClass().getName() : e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel.java
index 5c4f0c4..399728f 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel.java
@@ -24,7 +24,6 @@ import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
 import org.apache.commons.lang3.SerializationUtils;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.IdRepoConstants;
@@ -260,9 +259,8 @@ public abstract class SchedTaskDirectoryPanel<T extends SchedTaskTO>
                     target.add(container);
                     SchedTaskDirectoryPanel.this.getTogglePanel().close(target);
                 } catch (SyncopeClientException e) {
-                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                            ? e.getClass().getName() : e.getMessage());
                     LOG.error("While deleting propagation task {}", taskTO.getKey(), e);
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/TaskStartAtTogglePanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/TaskStartAtTogglePanel.java
index aa32a34..da44c53 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/TaskStartAtTogglePanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/TaskStartAtTogglePanel.java
@@ -18,7 +18,6 @@
  */
 package org.apache.syncope.client.console.tasks;
 
-import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.ui.commons.Constants;
 import org.apache.syncope.client.console.pages.BasePage;
@@ -49,9 +48,7 @@ public class TaskStartAtTogglePanel extends StartAtTogglePanel {
                     toggle(target, false);
                     target.add(container);
                 } catch (SyncopeClientException e) {
-                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                            ? e.getClass().getName()
-                            : e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                     LOG.error("While running task {}", key, e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
@@ -61,7 +58,6 @@ public class TaskStartAtTogglePanel extends StartAtTogglePanel {
             protected void onError(final AjaxRequestTarget target) {
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
-
         });
     }
 
@@ -69,5 +65,4 @@ public class TaskStartAtTogglePanel extends StartAtTogglePanel {
     protected TaskRestClient getRestClient() {
         return new TaskRestClient();
     }
-
 }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/TemplatesTogglePanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/TemplatesTogglePanel.java
index 6de26bf..47e4de4 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/TemplatesTogglePanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/TemplatesTogglePanel.java
@@ -20,7 +20,6 @@ package org.apache.syncope.client.console.tasks;
 
 import java.io.Serializable;
 import java.util.List;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.layout.AnyObjectFormLayoutInfo;
@@ -161,10 +160,8 @@ public abstract class TemplatesTogglePanel extends TogglePanel<Serializable> {
                     send(container, Broadcast.EXACT, payload);
                     toggle(target, false);
                 } catch (SyncopeClientException e) {
-                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                            ? e.getClass().getName()
-                            : e.getMessage());
                     LOG.error("While editing template for {}", typeModel.getObject(), e);
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/BinaryFieldPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/BinaryFieldPanel.java
index 8ba5fcc..5ce72d7 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/BinaryFieldPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/BinaryFieldPanel.java
@@ -170,8 +170,7 @@ public class BinaryFieldPanel extends BaseBinaryFieldPanel {
                 try {
                     fileDownload.initiate(target);
                 } catch (Exception e) {
-                    SyncopeConsoleSession.get().error(
-                            StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                 }
             }
         };
@@ -297,8 +296,8 @@ public class BinaryFieldPanel extends BaseBinaryFieldPanel {
     }
 
     @Override
-    protected void sendError(final String message) {
-        SyncopeConsoleSession.get().error(message);
+    protected void sendError(final Exception exception) {
+        SyncopeConsoleSession.get().onException(exception);
     }
 
     @Override
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/JobActionPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/JobActionPanel.java
index 77a51d4..cab7860 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/JobActionPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/JobActionPanel.java
@@ -93,8 +93,7 @@ public class JobActionPanel extends WizardMgtPanel<Serializable> {
                         send(container, Broadcast.EXACT, new JobActionPayload(target));
                     } catch (Exception e) {
                         LOG.error("While stopping {}", jobTO.getRefDesc(), e);
-                        SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage()) ? e.getClass().getName()
-                                : e.getMessage());
+                        SyncopeConsoleSession.get().onException(e);
                     }
                     ((BasePage) getPage()).getNotificationPanel().refresh(target);
                 }
@@ -127,8 +126,7 @@ public class JobActionPanel extends WizardMgtPanel<Serializable> {
                         send(container, Broadcast.EXACT, new JobActionPayload(target));
                     } catch (Exception e) {
                         LOG.error("While starting {}", jobTO.getRefDesc(), e);
-                        SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage()) ? e.getClass().getName()
-                                : e.getMessage());
+                        SyncopeConsoleSession.get().onException(e);
                     }
                     ((BasePage) getPage()).getNotificationPanel().refresh(target);
                 }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/JobWidget.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/JobWidget.java
index 6396520..48cdbd8 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/JobWidget.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/JobWidget.java
@@ -25,6 +25,7 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Optional;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.ui.commons.Constants;
@@ -518,8 +519,7 @@ public class JobWidget extends BaseWidget {
                         }
                     } catch (SyncopeClientException e) {
                         LOG.error("While deleting object {}", jobTO.getRefKey(), e);
-                        SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage()) ? e.getClass().
-                                getName() : e.getMessage());
+                        SyncopeConsoleSession.get().onException(e);
                     }
                     ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
                 }
@@ -539,11 +539,13 @@ public class JobWidget extends BaseWidget {
         @SuppressWarnings("unchecked")
         public void onEvent(final IEvent<?> event) {
             if (event.getPayload() instanceof AjaxWizard.NewItemEvent) {
-                final AjaxRequestTarget target = AjaxWizard.NewItemEvent.class.cast(event.getPayload()).getTarget();
+                Optional<AjaxRequestTarget> target = ((AjaxWizard.NewItemEvent<?>) event.getPayload()).getTarget();
 
-                if (event.getPayload() instanceof AjaxWizard.NewItemCancelEvent
+                if (target.isPresent()
+                        && event.getPayload() instanceof AjaxWizard.NewItemCancelEvent
                         || event.getPayload() instanceof AjaxWizard.NewItemFinishEvent) {
-                    jobModal.close(target);
+
+                    jobModal.close(target.get());
                 }
             }
 
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/BaseAjaxWizardBuilder.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/BaseAjaxWizardBuilder.java
index dcf7d95..b64aabc 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/BaseAjaxWizardBuilder.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/BaseAjaxWizardBuilder.java
@@ -41,8 +41,8 @@ public abstract class BaseAjaxWizardBuilder<T extends Serializable> extends Ajax
     }
 
     @Override
-    protected void sendError(final String message) {
-        SyncopeConsoleSession.get().error(message);
+    protected void sendError(final Exception exception) {
+        SyncopeConsoleSession.get().onException(exception);
     }
 
     @Override
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/WizardMgtPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/WizardMgtPanel.java
index 12b37c6..fd24cb8 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/WizardMgtPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/WizardMgtPanel.java
@@ -23,6 +23,7 @@ import org.apache.syncope.client.ui.commons.wizards.AjaxWizard;
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Optional;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.ui.commons.Constants;
@@ -176,7 +177,7 @@ public abstract class WizardMgtPanel<T extends Serializable> extends AbstractWiz
             modal.close(target);
         } else if (event.getPayload() instanceof AjaxWizard.NewItemEvent) {
             final AjaxWizard.NewItemEvent<T> newItemEvent = AjaxWizard.NewItemEvent.class.cast(event.getPayload());
-            final AjaxRequestTarget target = newItemEvent.getTarget();
+            final Optional<AjaxRequestTarget> target = newItemEvent.getTarget();
             final T item = newItemEvent.getItem();
 
             final boolean modalPanelAvailable = newItemEvent.getModalPanel() != null || newItemPanelBuilder != null;
@@ -202,7 +203,7 @@ public abstract class WizardMgtPanel<T extends Serializable> extends AbstractWiz
                     final IModel<T> model = new CompoundPropertyModel<>(item);
                     modal.setFormModel(model);
 
-                    target.add(modal.setContent(modalPanel));
+                    target.ifPresent(t -> t.add(modal.setContent(modalPanel)));
 
                     modal.header(new StringResourceModel(
                             String.format("any.%s", newItemEvent.getEventDescription()),
@@ -218,17 +219,25 @@ public abstract class WizardMgtPanel<T extends Serializable> extends AbstractWiz
                     fragment.add(Component.class.cast(modalPanel));
                     container.addOrReplace(fragment);
                 }
-                customActionCallback(target);
+                if (target.isPresent()) {
+                    customActionCallback(target.get());
+                }
             } else if (event.getPayload() instanceof AjaxWizard.NewItemCancelEvent) {
                 if (wizardInModal) {
-                    modal.close(target);
+                    if (target.isPresent()) {
+                        modal.close(target.get());
+                    }
                 } else {
                     container.addOrReplace(initialFragment);
                 }
-                customActionOnCancelCallback(target);
+                if (target.isPresent()) {
+                    customActionOnCancelCallback(target.get());
+                }
             } else if (event.getPayload() instanceof AjaxWizard.NewItemFinishEvent) {
                 SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
-                ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
+                if (target.isPresent()) {
+                    ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target.get());
+                }
 
                 if (wizardInModal && showResultPage) {
                     modal.setContent(new ResultPage<T>(
@@ -247,17 +256,21 @@ public abstract class WizardMgtPanel<T extends Serializable> extends AbstractWiz
                             return WizardMgtPanel.this.customResultBody(id, item, result);
                         }
                     });
-                    target.add(modal.getForm());
+                    target.ifPresent(t -> t.add(modal.getForm()));
                 } else if (wizardInModal) {
-                    modal.close(target);
+                    if (target.isPresent()) {
+                        modal.close(target.get());
+                    }
                 } else {
                     container.addOrReplace(initialFragment);
                 }
-                customActionOnFinishCallback(target);
+                if (target.isPresent()) {
+                    customActionOnFinishCallback(target.get());
+                }
             }
 
             if (containerAutoRefresh) {
-                target.add(container);
+                target.ifPresent(t -> t.add(container));
             }
         }
         super.onEvent(event);
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java
index eca6f8a..ff9a581 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java
@@ -219,8 +219,8 @@ public abstract class AnyWizardBuilder<A extends AnyTO> extends AbstractAnyWizar
     }
 
     @Override
-    protected void sendError(final String message) {
-        SyncopeConsoleSession.get().error(message);
+    protected void sendError(final Exception exception) {
+        SyncopeConsoleSession.get().onException(exception);
     }
 
     @Override
@@ -231,6 +231,7 @@ public abstract class AnyWizardBuilder<A extends AnyTO> extends AbstractAnyWizar
     @Override
     protected Future<Pair<Serializable, Serializable>> execute(
             final Callable<Pair<Serializable, Serializable>> future) {
+
         return SyncopeConsoleSession.get().execute(future);
     }
 }
diff --git a/client/idrepo/console/src/test/java/org/apache/syncope/client/console/SyncopeConsoleApplicationTest.java b/client/idrepo/console/src/test/java/org/apache/syncope/client/console/SyncopeConsoleApplicationTest.java
index a1f0bd1..a0eccc2 100644
--- a/client/idrepo/console/src/test/java/org/apache/syncope/client/console/SyncopeConsoleApplicationTest.java
+++ b/client/idrepo/console/src/test/java/org/apache/syncope/client/console/SyncopeConsoleApplicationTest.java
@@ -19,14 +19,24 @@
 package org.apache.syncope.client.console;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.io.IOException;
+import java.security.AccessControlException;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.concurrent.ExecutionException;
+import javax.ws.rs.BadRequestException;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.pages.Dashboard;
 import org.apache.syncope.client.console.pages.Login;
+import org.apache.syncope.common.lib.SyncopeClientCompositeException;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.wicket.feedback.FeedbackMessage;
 import org.apache.wicket.util.tester.FormTester;
 import org.junit.jupiter.api.Test;
 
@@ -66,4 +76,61 @@ public class SyncopeConsoleApplicationTest extends AbstractTest {
         TESTER.assertRenderedPage(Dashboard.class);
         securityHeaders.forEach((key, value) -> assertEquals(value, TESTER.getLastResponse().getHeader(key)));
     }
+
+    @Test
+    public void errors() {
+        SyncopeConsoleSession session = SyncopeConsoleSession.get();
+
+        assertNull(session.getFeedbackMessages().first());
+
+        session.onException(new AccessControlException("JWT Expired"));
+        FeedbackMessage message = session.getFeedbackMessages().first();
+        assertNotNull(message);
+        assertTrue(message.isError());
+        assertEquals(SyncopeConsoleSession.Error.SESSION_EXPIRED.fallback(), message.getMessage());
+        session.getFeedbackMessages().clear();
+
+        session.onException(new AccessControlException("Auth Exception"));
+        message = session.getFeedbackMessages().first();
+        assertNotNull(message);
+        assertTrue(message.isError());
+        assertEquals(SyncopeConsoleSession.Error.AUTHORIZATION.fallback(), message.getMessage());
+        session.getFeedbackMessages().clear();
+
+        session.onException(new BadRequestException());
+        message = session.getFeedbackMessages().first();
+        assertNotNull(message);
+        assertTrue(message.isError());
+        assertEquals(SyncopeConsoleSession.Error.REST.fallback(), message.getMessage());
+        session.getFeedbackMessages().clear();
+
+        SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidUser);
+        sce.getElements().add("Error 1");
+        session.onException(sce);
+        message = session.getFeedbackMessages().first();
+        assertNotNull(message);
+        assertTrue(message.isError());
+        assertEquals("Error 1", message.getMessage());
+        session.getFeedbackMessages().clear();
+
+        sce = SyncopeClientException.build(ClientExceptionType.InvalidUser);
+        sce.getElements().add("Error 1");
+        sce.getElements().add("Error 2");
+        session.onException(sce);
+        message = session.getFeedbackMessages().first();
+        assertNotNull(message);
+        assertTrue(message.isError());
+        assertEquals("Error 1, Error 2", message.getMessage());
+        session.getFeedbackMessages().clear();
+
+        SyncopeClientCompositeException scce = SyncopeClientException.buildComposite();
+        scce.addException(SyncopeClientException.build(ClientExceptionType.InvalidUser));
+        scce.addException(SyncopeClientException.build(ClientExceptionType.InvalidExternalResource));
+        session.onException(new ExecutionException(scce));
+        message = session.getFeedbackMessages().first();
+        assertNotNull(message);
+        assertTrue(message.isError());
+        assertEquals(scce.getMessage(), message.getMessage());
+        session.getFeedbackMessages().clear();
+    }
 }
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserSession.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserSession.java
index c1358b4..a7a3dd2 100644
--- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserSession.java
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserSession.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.client.enduser;
 
+import java.security.AccessControlException;
 import java.text.DateFormat;
 import java.util.Collections;
 import java.util.HashMap;
@@ -26,16 +27,21 @@ import java.util.Optional;
 import java.util.concurrent.Callable;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.Future;
+import java.util.stream.Collectors;
+import javax.ws.rs.BadRequestException;
 import javax.ws.rs.ForbiddenException;
 import javax.ws.rs.core.EntityTag;
 import javax.ws.rs.core.MediaType;
+import javax.xml.ws.WebServiceException;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.apache.commons.lang3.time.FastDateFormat;
 import org.apache.cxf.jaxrs.client.WebClient;
 import org.apache.syncope.client.lib.AnonymousAuthenticationHandler;
 import org.apache.syncope.client.lib.SyncopeClient;
 import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
 import org.apache.syncope.client.ui.commons.BaseSession;
+import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.IdRepoEntitlement;
@@ -91,6 +97,32 @@ public class SyncopeEnduserSession extends WebSession implements BaseSession {
         executor.initialize();
     }
 
+    @Override
+    public void onException(final Exception e) {
+        Throwable root = ExceptionUtils.getRootCause(e);
+        String message = root.getMessage();
+
+        if (root instanceof SyncopeClientException) {
+            SyncopeClientException sce = (SyncopeClientException) root;
+            if (!sce.isComposite()) {
+                message = sce.getElements().stream().collect(Collectors.joining(", "));
+            }
+        } else if (root instanceof AccessControlException || root instanceof ForbiddenException) {
+            Error error = StringUtils.containsIgnoreCase(message, "expired")
+                    ? Error.SESSION_EXPIRED
+                    : Error.AUTHORIZATION;
+            message = getApplication().getResourceSettings().getLocalizer().
+                    getString(error.key(), null, null, null, null, error.fallback());
+        } else if (root instanceof BadRequestException || root instanceof WebServiceException) {
+            message = getApplication().getResourceSettings().getLocalizer().
+                    getString(Error.REST.key(), null, null, null, null, Error.REST.fallback());
+        }
+
+        message = getApplication().getResourceSettings().getLocalizer().
+                getString(message, null, null, null, null, message);
+        error(message);
+    }
+
     public void cleanup() {
         client = null;
         selfTO = null;
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/markup/html/form/BinaryFieldPanel.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/markup/html/form/BinaryFieldPanel.java
index cc6cffb..e7a629e 100644
--- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/markup/html/form/BinaryFieldPanel.java
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/markup/html/form/BinaryFieldPanel.java
@@ -169,8 +169,7 @@ public class BinaryFieldPanel extends BaseBinaryFieldPanel {
                 try {
                     fileDownload.initiate(target);
                 } catch (Exception e) {
-                    SyncopeEnduserSession.get().error(
-                            StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
+                    SyncopeEnduserSession.get().onException(e);
                 }
             }
         };
@@ -294,8 +293,8 @@ public class BinaryFieldPanel extends BaseBinaryFieldPanel {
     }
 
     @Override
-    protected void sendError(final String message) {
-        SyncopeEnduserSession.get().error(message);
+    protected void sendError(final Exception exception) {
+        SyncopeEnduserSession.get().onException(exception);
     }
 
     @Override
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/MustChangePassword.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/MustChangePassword.java
index 156c64c..0480618 100644
--- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/MustChangePassword.java
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/MustChangePassword.java
@@ -18,7 +18,6 @@
  */
 package org.apache.syncope.client.enduser.pages;
 
-import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.enduser.SyncopeEnduserSession;
 import org.apache.syncope.client.enduser.rest.UserSelfRestClient;
 import org.apache.syncope.client.ui.commons.Constants;
@@ -50,8 +49,7 @@ public class MustChangePassword extends AbstractMustChangePassword {
         } catch (Exception e) {
             LOG.error("While changing password for {}",
                     SyncopeEnduserSession.get().getSelfTO().getUsername(), e);
-            SyncopeEnduserSession.get().error(StringUtils.isBlank(e.getMessage())
-                    ? e.getClass().getName() : e.getMessage());
+            SyncopeEnduserSession.get().onException(e);
             notificationPanel.refresh(target);
         }
     }
@@ -65,5 +63,4 @@ public class MustChangePassword extends AbstractMustChangePassword {
     protected void doCancel() {
         setResponsePage(getApplication().getHomePage());
     }
-
 }
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset.java
index 487b15f..0051526 100644
--- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset.java
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset.java
@@ -21,7 +21,6 @@ package org.apache.syncope.client.enduser.pages;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.stream.Collectors;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.enduser.SyncopeEnduserSession;
 import org.apache.syncope.client.ui.commons.Constants;
 import org.apache.syncope.client.ui.commons.DomainDropDown;
@@ -138,9 +137,7 @@ public class SelfConfirmPasswordReset extends BaseEnduserWebPage {
                     setResponsePage(getApplication().getHomePage(), parameters);
                 } catch (SyncopeClientException sce) {
                     LOG.error("Unable to complete the 'Password Reset Confirmation' process", sce);
-                    SyncopeEnduserSession.get().error(StringUtils.isBlank(sce.getMessage())
-                            ? sce.getClass().getName()
-                            : sce.getMessage());
+                    SyncopeEnduserSession.get().onException(sce);
                     ((BaseEnduserWebPage) getPageReference().getPage()).getNotificationPanel().refresh(target);
                 }
             }
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/SelfPwdResetPanel.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/SelfPwdResetPanel.java
index bdec2a5..46cda9c 100644
--- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/SelfPwdResetPanel.java
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/SelfPwdResetPanel.java
@@ -21,7 +21,6 @@ package org.apache.syncope.client.enduser.panels;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.stream.Collectors;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.enduser.SyncopeEnduserSession;
 import org.apache.syncope.client.enduser.SyncopeWebApplication;
 import org.apache.syncope.client.enduser.pages.BaseEnduserWebPage;
@@ -178,9 +177,7 @@ public class SelfPwdResetPanel extends Panel implements IEventSource {
                         setResponsePage(getApplication().getHomePage(), parameters);
                     } catch (SyncopeClientException sce) {
                         LOG.error("Unable to reset password of [{}]", usernameText, sce);
-                        SyncopeEnduserSession.get().error(StringUtils.isBlank(sce.getMessage())
-                                ? sce.getClass().getName()
-                                : sce.getMessage());
+                        SyncopeEnduserSession.get().onException(sce);
                         ((BaseEnduserWebPage) pageRef.getPage()).getNotificationPanel().refresh(target);
                     }
                 }
@@ -215,11 +212,8 @@ public class SelfPwdResetPanel extends Panel implements IEventSource {
             target.add(securityQuestion);
         } catch (Exception e) {
             LOG.error("Unable to get security question for [{}]", usernameText, e);
-            SyncopeEnduserSession.get().error(StringUtils.isBlank(e.getMessage())
-                    ? e.getClass().getName()
-                    : e.getMessage());
+            SyncopeEnduserSession.get().onException(e);
             ((BaseEnduserWebPage) pageRef.getPage()).getNotificationPanel().refresh(target);
         }
     }
-
 }
diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/wizards/any/AnyWizardBuilder.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/wizards/any/AnyWizardBuilder.java
index ba07c04..13c3339 100644
--- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/wizards/any/AnyWizardBuilder.java
+++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/wizards/any/AnyWizardBuilder.java
@@ -150,8 +150,8 @@ public abstract class AnyWizardBuilder extends AbstractAnyWizardBuilder<UserTO>
     }
 
     @Override
-    protected void sendError(final String message) {
-        SyncopeEnduserSession.get().error(message);
+    protected void sendError(final Exception exception) {
+        SyncopeEnduserSession.get().onException(exception);
     }
 
     @Override
@@ -208,8 +208,8 @@ public abstract class AnyWizardBuilder extends AbstractAnyWizardBuilder<UserTO>
             }
 
             @Override
-            protected void sendError(final String message) {
-                AnyWizardBuilder.this.sendError(message);
+            protected void sendError(final Exception exception) {
+                SyncopeEnduserSession.get().onException(exception);
             }
 
             @Override
diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/SyncopeClientException.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/SyncopeClientException.java
index f17d5e5..9d0a634 100644
--- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/SyncopeClientException.java
+++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/SyncopeClientException.java
@@ -91,5 +91,4 @@ public class SyncopeClientException extends RuntimeException {
     public String getLocalizedMessage() {
         return getMessage();
     }
-
 }
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/ExceptionUtils2.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/ExceptionUtils2.java
index a97c2eb..8a2f63b 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/ExceptionUtils2.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/utils/ExceptionUtils2.java
@@ -31,9 +31,8 @@ public final class ExceptionUtils2 {
     public static String getFullStackTrace(final Throwable t) {
         StringBuilder result = new StringBuilder();
 
-        for (Throwable throwable : ExceptionUtils.getThrowableList(t)) {
-            result.append(ExceptionUtils.getStackTrace(throwable)).append("\n\n");
-        }
+        ExceptionUtils.getThrowableList(t).
+                forEach(throwable -> result.append(ExceptionUtils.getStackTrace(throwable)).append("\n\n"));
 
         return result.toString();
     }
diff --git a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/panels/BpmnProcessDirectoryPanel.java b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/panels/BpmnProcessDirectoryPanel.java
index fd0fc1d..285ee56 100644
--- a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/panels/BpmnProcessDirectoryPanel.java
+++ b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/panels/BpmnProcessDirectoryPanel.java
@@ -99,8 +99,8 @@ public class BpmnProcessDirectoryPanel extends DirectoryPanel<
             }
 
             @Override
-            protected void sendError(final String message) {
-                SyncopeConsoleSession.get().error(message);
+            protected void sendError(final Exception exception) {
+                SyncopeConsoleSession.get().onException(exception);
             }
 
             @Override
@@ -204,8 +204,7 @@ public class BpmnProcessDirectoryPanel extends DirectoryPanel<
                                 utility.show(false);
                                 utility.close(target);
                             } catch (SyncopeClientException e) {
-                                SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                                        ? e.getClass().getName() : e.getMessage());
+                                SyncopeConsoleSession.get().onException(e);
                             }
                             ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
                         }
@@ -271,8 +270,7 @@ public class BpmnProcessDirectoryPanel extends DirectoryPanel<
                     target.add(container);
                 } catch (SyncopeClientException e) {
                     LOG.error("While deleting BPMN definition {}", model.getObject().getName(), e);
-                    SyncopeConsoleSession.get().error(
-                            StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
diff --git a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/panels/NewBpmnProcess.java b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/panels/NewBpmnProcess.java
index d427537..7c6ba98 100644
--- a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/panels/NewBpmnProcess.java
+++ b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/panels/NewBpmnProcess.java
@@ -21,7 +21,6 @@ package org.apache.syncope.client.console.panels;
 import java.io.Serializable;
 import javax.ws.rs.core.MediaType;
 import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.pdfbox.util.Charsets;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.ui.commons.Constants;
@@ -69,9 +68,7 @@ public class NewBpmnProcess extends TogglePanel<Serializable> {
                     target.add(container);
                 } catch (Exception e) {
                     LOG.error("While creating new BPMN process", e);
-                    SyncopeConsoleSession.get().error(
-                            StringUtils.isBlank(e.getMessage())
-                            ? e.getClass().getName() : e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
diff --git a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/panels/UserRequestDirectoryPanel.java b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/panels/UserRequestDirectoryPanel.java
index cc1c9df..524710c 100644
--- a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/panels/UserRequestDirectoryPanel.java
+++ b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/panels/UserRequestDirectoryPanel.java
@@ -23,7 +23,6 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.ui.commons.Constants;
 import org.apache.syncope.client.ui.commons.DirectoryDataProvider;
@@ -97,9 +96,8 @@ public class UserRequestDirectoryPanel
                     target.add(container);
                     UserRequestDirectoryPanel.this.getTogglePanel().close(target);
                 } catch (SyncopeClientException e) {
-                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                            ? e.getClass().getName() : e.getMessage());
                     LOG.error("While canceling execution {}", model.getObject().getExecutionId(), e);
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
diff --git a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/panels/UserRequestFormDirectoryPanel.java b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/panels/UserRequestFormDirectoryPanel.java
index 833edd6..2dd0fb1 100644
--- a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/panels/UserRequestFormDirectoryPanel.java
+++ b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/panels/UserRequestFormDirectoryPanel.java
@@ -195,11 +195,10 @@ public class UserRequestFormDirectoryPanel
 
                             UserRequestFormDirectoryPanel.this.getTogglePanel().close(target);
                         } catch (SyncopeClientException e) {
-                            SyncopeConsoleSession.get().error(getString(Constants.ERROR) + ": " + e.getMessage());
+                            SyncopeConsoleSession.get().onException(e);
                         }
                         ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
                     }
-
                 }));
 
                 manageFormModal.header(new Model<>(getString("form.manage", new Model<>(model.getObject()))));
@@ -320,7 +319,7 @@ public class UserRequestFormDirectoryPanel
         try {
             UserRequestRestClient.claimForm(taskId);
         } catch (SyncopeClientException scee) {
-            SyncopeConsoleSession.get().error(getString(Constants.ERROR) + ": " + scee.getMessage());
+            SyncopeConsoleSession.get().onException(scee);
         }
     }
 
@@ -328,7 +327,7 @@ public class UserRequestFormDirectoryPanel
         try {
             UserRequestRestClient.unclaimForm(taskId);
         } catch (SyncopeClientException scee) {
-            SyncopeConsoleSession.get().error(getString(Constants.ERROR) + ": " + scee.getMessage());
+            SyncopeConsoleSession.get().onException(scee);
         }
     }
 
@@ -372,7 +371,7 @@ public class UserRequestFormDirectoryPanel
             } else {
                 result = userRestClient.update(getOriginalItem().getInnerObject().getETagValue(), userUR);
                 UserRequestRestClient.getForm(result.getEntity().getKey())
-                    .ifPresent(form -> claimForm(form.getTaskId()));
+                        .ifPresent(form -> claimForm(form.getTaskId()));
             }
 
             return result;
diff --git a/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/panels/OIDCProvidersDirectoryPanel.java b/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/panels/OIDCProvidersDirectoryPanel.java
index df92251..907ba9f 100644
--- a/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/panels/OIDCProvidersDirectoryPanel.java
+++ b/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/panels/OIDCProvidersDirectoryPanel.java
@@ -226,8 +226,7 @@ public class OIDCProvidersDirectoryPanel extends DirectoryPanel<
                     target.add(container);
                 } catch (SyncopeClientException e) {
                     LOG.error("While deleting object {}", model.getObject().getKey(), e);
-                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                            ? e.getClass().getName() : e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
@@ -243,16 +242,16 @@ public class OIDCProvidersDirectoryPanel extends DirectoryPanel<
             AjaxWizard.NewItemEvent<?> newItemEvent = AjaxWizard.NewItemEvent.class.cast(event.getPayload());
             WizardModalPanel<?> modalPanel = newItemEvent.getModalPanel();
 
-            if (event.getPayload() instanceof AjaxWizard.NewItemActionEvent && modalPanel != null) {
+            if (newItemEvent instanceof AjaxWizard.NewItemActionEvent && modalPanel != null) {
                 final IModel<Serializable> model = new CompoundPropertyModel<>(modalPanel.getItem());
                 templateModal.setFormModel(model);
                 templateModal.header(newItemEvent.getResourceModel());
-                newItemEvent.getTarget().add(templateModal.setContent(modalPanel));
+                newItemEvent.getTarget().ifPresent(target -> target.add(templateModal.setContent(modalPanel)));
                 templateModal.show(true);
-            } else if (event.getPayload() instanceof AjaxWizard.NewItemCancelEvent) {
-                templateModal.close(newItemEvent.getTarget());
-            } else if (event.getPayload() instanceof AjaxWizard.NewItemFinishEvent) {
-                templateModal.close(newItemEvent.getTarget());
+            } else if (newItemEvent instanceof AjaxWizard.NewItemCancelEvent) {
+                newItemEvent.getTarget().ifPresent(target -> templateModal.close(target));
+            } else if (newItemEvent instanceof AjaxWizard.NewItemFinishEvent) {
+                newItemEvent.getTarget().ifPresent(target -> templateModal.close(target));
             }
         }
     }
@@ -286,6 +285,5 @@ public class OIDCProvidersDirectoryPanel extends DirectoryPanel<
         public IModel<OIDCProviderTO> model(final OIDCProviderTO object) {
             return new CompoundPropertyModel<>(object);
         }
-
     }
 }
diff --git a/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder.java b/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder.java
index 7ff0193..0e5574e 100644
--- a/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder.java
+++ b/ext/oidcclient/client-console/src/main/java/org/apache/syncope/client/console/wizards/OIDCProviderWizardBuilder.java
@@ -122,8 +122,8 @@ public class OIDCProviderWizardBuilder extends AjaxWizardBuilder<OIDCProviderTO>
     }
 
     @Override
-    protected void sendError(final String message) {
-        SyncopeConsoleSession.get().error(message);
+    protected void sendError(final Exception exception) {
+        SyncopeConsoleSession.get().onException(exception);
     }
 
     @Override
diff --git a/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/panels/ImportMetadata.java b/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/panels/ImportMetadata.java
index ed47bea..c515e68 100644
--- a/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/panels/ImportMetadata.java
+++ b/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/panels/ImportMetadata.java
@@ -24,7 +24,6 @@ import java.io.ByteArrayInputStream;
 import java.io.Serializable;
 import java.util.ArrayList;
 import org.apache.commons.lang3.ArrayUtils;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.ui.commons.Constants;
 import org.apache.syncope.client.console.pages.BasePage;
@@ -90,9 +89,7 @@ public class ImportMetadata extends TogglePanel<Serializable> {
                         target.add(container);
                     } catch (Exception e) {
                         LOG.error("While importing SAML 2.0 IdP metadata", e);
-                        SyncopeConsoleSession.get().error(
-                                StringUtils.isBlank(e.getMessage())
-                                ? e.getClass().getName() : e.getMessage());
+                        SyncopeConsoleSession.get().onException(e);
                     }
                     ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
                 }
@@ -104,5 +101,4 @@ public class ImportMetadata extends TogglePanel<Serializable> {
             }
         });
     }
-
 }
diff --git a/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel.java b/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel.java
index d3b5e29..4ff620e 100644
--- a/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel.java
+++ b/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel.java
@@ -276,8 +276,7 @@ public class SAML2IdPsDirectoryPanel extends DirectoryPanel<
                     target.add(container);
                 } catch (SyncopeClientException e) {
                     LOG.error("While deleting object {}", model.getObject().getKey(), e);
-                    SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                            ? e.getClass().getName() : e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                 }
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
             }
@@ -294,16 +293,16 @@ public class SAML2IdPsDirectoryPanel extends DirectoryPanel<
             AjaxWizard.NewItemEvent<?> newItemEvent = AjaxWizard.NewItemEvent.class.cast(event.getPayload());
             WizardModalPanel<?> modalPanel = newItemEvent.getModalPanel();
 
-            if (event.getPayload() instanceof AjaxWizard.NewItemActionEvent && modalPanel != null) {
+            if (newItemEvent instanceof AjaxWizard.NewItemActionEvent && modalPanel != null) {
                 final IModel<Serializable> model = new CompoundPropertyModel<>(modalPanel.getItem());
                 templateModal.setFormModel(model);
                 templateModal.header(newItemEvent.getResourceModel());
-                newItemEvent.getTarget().add(templateModal.setContent(modalPanel));
+                newItemEvent.getTarget().ifPresent(target -> target.add(templateModal.setContent(modalPanel)));
                 templateModal.show(true);
-            } else if (event.getPayload() instanceof AjaxWizard.NewItemCancelEvent) {
-                templateModal.close(newItemEvent.getTarget());
-            } else if (event.getPayload() instanceof AjaxWizard.NewItemFinishEvent) {
-                templateModal.close(newItemEvent.getTarget());
+            } else if (newItemEvent instanceof AjaxWizard.NewItemCancelEvent) {
+                newItemEvent.getTarget().ifPresent(target -> templateModal.close(target));
+            } else if (newItemEvent instanceof AjaxWizard.NewItemFinishEvent) {
+                newItemEvent.getTarget().ifPresent(target -> templateModal.close(target));
             }
         }
     }
diff --git a/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/panels/SAML2SPPanel.java b/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/panels/SAML2SPPanel.java
index 25eb122..81bfeef 100644
--- a/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/panels/SAML2SPPanel.java
+++ b/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/panels/SAML2SPPanel.java
@@ -20,7 +20,6 @@ package org.apache.syncope.client.console.panels;
 
 import javax.ws.rs.client.ClientBuilder;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
-import org.apache.syncope.client.ui.commons.Constants;
 import org.apache.syncope.client.ui.commons.HttpResourceStream;
 import org.apache.wicket.markup.html.link.Link;
 import org.apache.wicket.markup.html.panel.Panel;
@@ -62,10 +61,9 @@ public class SAML2SPPanel extends Panel {
                     getRequestCycle().scheduleRequestHandlerAfterCurrent(rsrh);
                 } catch (Exception e) {
                     LOG.error("While exporting SAML 2.0 SP metadata", e);
-                    SyncopeConsoleSession.get().error(getString(Constants.ERROR) + ": " + e.getMessage());
+                    SyncopeConsoleSession.get().onException(e);
                 }
             }
         });
     }
-
 }
diff --git a/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPWizardBuilder.java b/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPWizardBuilder.java
index b28aac0..d30a593 100644
--- a/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPWizardBuilder.java
+++ b/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPWizardBuilder.java
@@ -117,8 +117,8 @@ public class SAML2IdPWizardBuilder extends AjaxWizardBuilder<SAML2IdPTO> {
     }
 
     @Override
-    protected void sendError(final String message) {
-        SyncopeConsoleSession.get().error(message);
+    protected void sendError(final Exception exception) {
+        SyncopeConsoleSession.get().onException(exception);
     }
 
     @Override
@@ -129,6 +129,7 @@ public class SAML2IdPWizardBuilder extends AjaxWizardBuilder<SAML2IdPTO> {
     @Override
     protected Future<Pair<Serializable, Serializable>> execute(
             final Callable<Pair<Serializable, Serializable>> future) {
+
         return SyncopeConsoleSession.get().execute(future);
     }
 
diff --git a/ext/scimv2/client-console/src/main/java/org/apache/syncope/client/console/pages/SCIMConfPage.java b/ext/scimv2/client-console/src/main/java/org/apache/syncope/client/console/pages/SCIMConfPage.java
index 7665a98..66775c0 100644
--- a/ext/scimv2/client-console/src/main/java/org/apache/syncope/client/console/pages/SCIMConfPage.java
+++ b/ext/scimv2/client-console/src/main/java/org/apache/syncope/client/console/pages/SCIMConfPage.java
@@ -20,7 +20,6 @@ package org.apache.syncope.client.console.pages;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
 import java.io.Serializable;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.BookmarkablePageLinkBuilder;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.annotations.ExtPage;
@@ -83,8 +82,7 @@ public class SCIMConfPage extends BaseExtPage {
                             target.add(content);
                         } catch (Exception e) {
                             LOG.error("While setting SCIM configuration", e);
-                            SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage())
-                                    ? e.getClass().getName() : e.getMessage());
+                            SyncopeConsoleSession.get().onException(e);
                         }
                         ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
                     }
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AbstractConsoleITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AbstractConsoleITCase.java
index 6e890bc..2c5615a 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AbstractConsoleITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AbstractConsoleITCase.java
@@ -23,12 +23,11 @@ import com.giffing.wicket.spring.boot.context.extensions.boot.actuator.WicketEnd
 import com.giffing.wicket.spring.boot.starter.app.classscanner.candidates.WicketClassCandidatesHolder;
 import com.giffing.wicket.spring.boot.starter.configuration.extensions.core.settings.general.GeneralSettingsProperties;
 import com.giffing.wicket.spring.boot.starter.configuration.extensions.external.spring.boot.actuator.WicketEndpointRepositoryDefault;
-
 import java.util.List;
+import java.util.Locale;
 import org.apache.syncope.client.console.SyncopeIdMConsoleContext;
 import org.apache.syncope.client.console.SyncopeWebApplication;
 import org.apache.syncope.client.console.commons.PreviewUtils;
-import java.util.Locale;
 import org.apache.syncope.client.console.init.ClassPathScanImplementationLookup;
 import org.apache.syncope.client.console.init.MIMETypesLoader;
 import org.apache.syncope.client.console.pages.Login;
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AbstractTypesITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AbstractTypesITCase.java
index aa8ae80..787cd44 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AbstractTypesITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AbstractTypesITCase.java
@@ -106,8 +106,7 @@ public abstract class AbstractTypesITCase extends AbstractConsoleITCase {
                 + "accordionPanel:tabs:0:body:content:outerObjectsRepeater:0:outer:form");
         formTester.submit("content:form:buttons:finish");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
-
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
     }
 
@@ -125,8 +124,7 @@ public abstract class AbstractTypesITCase extends AbstractConsoleITCase {
         TESTER.clearFeedbackMessages();
         TESTER.clickLink(
                 "body:content:tabbedPanel:panel:outerObjectsRepeater:0:outer:dialog:footer:inputs:0:submit");
-        TESTER.assertInfoMessages("Operation successfully executed");
-
+        assertSuccessMessage();
         TESTER.clearFeedbackMessages();
     }
 
@@ -143,8 +141,7 @@ public abstract class AbstractTypesITCase extends AbstractConsoleITCase {
 
         TESTER.clickLink(
                 "body:content:tabbedPanel:panel:outerObjectsRepeater:0:outer:dialog:footer:inputs:0:submit");
-        TESTER.assertInfoMessages("Operation successfully executed");
-
+        assertSuccessMessage();
         TESTER.clearFeedbackMessages();
     }
 
@@ -164,9 +161,10 @@ public abstract class AbstractTypesITCase extends AbstractConsoleITCase {
 
         TESTER.clickLink(
                 "body:content:tabbedPanel:panel:outerObjectsRepeater:0:outer:dialog:footer:inputs:0:submit");
-        TESTER.assertInfoMessages("Operation successfully executed");
 
+        assertSuccessMessage();
         TESTER.clearFeedbackMessages();
+
         TESTER.assertRenderedPage(Types.class);
     }
 }
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AnyObjectsITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AnyObjectsITCase.java
index 910edde..17d1789 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AnyObjectsITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AnyObjectsITCase.java
@@ -71,7 +71,7 @@ public class AnyObjectsITCase extends AbstractConsoleITCase {
         assertNotNull(component);
 
         TESTER.executeAjaxEvent(component.getPageRelativePath(), Constants.ON_CLICK);
-        TESTER.clickLink(TAB_PANEL 
+        TESTER.clickLink(TAB_PANEL
                 + "outerObjectsRepeater:1:outer:container:content:togglePanelContainer:container:"
                 + "actions:actions:actionRepeater:5:action:action");
 
@@ -120,7 +120,7 @@ public class AnyObjectsITCase extends AbstractConsoleITCase {
         assertNotNull(formTester);
         formTester.submit("buttons:finish");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
 
         TESTER.assertComponent(TAB_PANEL
                 + "outerObjectsRepeater:0:outer:form:content:customResultBody:resources:"
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AnyTypeClassesITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AnyTypeClassesITCase.java
index 4c02d14..02bb09a 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AnyTypeClassesITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AnyTypeClassesITCase.java
@@ -68,7 +68,7 @@ public class AnyTypeClassesITCase extends AbstractTypesITCase {
         TESTER.clearFeedbackMessages();
         TESTER.clickLink(
                 "body:content:tabbedPanel:panel:outerObjectsRepeater:0:outer:dialog:footer:inputs:0:submit");
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
 
         TESTER.clearFeedbackMessages();
         TESTER.assertRenderedPage(Types.class);
@@ -107,7 +107,7 @@ public class AnyTypeClassesITCase extends AbstractTypesITCase {
 
         TESTER.clickLink(
                 "body:content:tabbedPanel:panel:outerObjectsRepeater:0:outer:dialog:footer:inputs:0:submit");
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         component = findComponentByProp(KEY, DATATABLE_PATH, name);
@@ -126,10 +126,10 @@ public class AnyTypeClassesITCase extends AbstractTypesITCase {
                 + "togglePanelContainer:container:actions:actions:actionRepeater:1:action:action"),
                 Constants.ON_CLICK);
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
-        component = findComponentByProp(KEY, DATATABLE_PATH, name);
 
+        component = findComponentByProp(KEY, DATATABLE_PATH, name);
         assertNull(component);
     }
 
@@ -156,11 +156,10 @@ public class AnyTypeClassesITCase extends AbstractTypesITCase {
                 + "togglePanelContainer:container:actions:actions:actionRepeater:1:action:action"),
                 Constants.ON_CLICK);
 
-        TESTER.assertInfoMessages("Operation successfully executed");
-
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
-        component = findComponentByProp(KEY, DATATABLE_PATH, anyTypeClassName);
 
+        component = findComponentByProp(KEY, DATATABLE_PATH, anyTypeClassName);
         assertNull(component);
     }
 }
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AnyTypesITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AnyTypesITCase.java
index 3a35499..63f4147 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AnyTypesITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AnyTypesITCase.java
@@ -73,7 +73,7 @@ public class AnyTypesITCase extends AbstractTypesITCase {
         TESTER.clearFeedbackMessages();
         TESTER.clickLink(
                 "body:content:tabbedPanel:panel:outerObjectsRepeater:0:outer:dialog:footer:inputs:0:submit");
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
 
         TESTER.clearFeedbackMessages();
         TESTER.assertRenderedPage(Types.class);
@@ -118,7 +118,7 @@ public class AnyTypesITCase extends AbstractTypesITCase {
         TESTER.clearFeedbackMessages();
         TESTER.clickLink(
                 "body:content:tabbedPanel:panel:outerObjectsRepeater:0:outer:dialog:footer:inputs:0:submit");
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
     }
 
     @Test
@@ -145,11 +145,10 @@ public class AnyTypesITCase extends AbstractTypesITCase {
                 + "togglePanelContainer:container:actions:actions:actionRepeater:1:action:action"),
                 Constants.ON_CLICK);
 
-        TESTER.assertInfoMessages("Operation successfully executed");
-
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
-        component = findComponentByProp(KEY, DATATABLE_PATH, name);
 
+        component = findComponentByProp(KEY, DATATABLE_PATH, name);
         assertNull(component);
     }
 }
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/BatchesITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/BatchesITCase.java
index 0b00d90..0021a28 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/BatchesITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/BatchesITCase.java
@@ -170,7 +170,7 @@ public class BatchesITCase extends AbstractConsoleITCase {
                 + "second:container:actions:actionRepeater:0:action:action",
                 Constants.ON_CLICK);
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         TESTER.assertLabel(TAB_PANEL + "outerObjectsRepeater:2:outer:form:content:status:"
@@ -228,7 +228,7 @@ public class BatchesITCase extends AbstractConsoleITCase {
                 + "second:container:actions:actionRepeater:1:action:action",
                 Constants.ON_CLICK);
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         TESTER.assertLabel(TAB_PANEL + "outerObjectsRepeater:2:outer:form:content:status:"
@@ -314,7 +314,7 @@ public class BatchesITCase extends AbstractConsoleITCase {
         TESTER.executeAjaxEvent(component.getPageRelativePath(), Constants.ON_CLICK);
         // manage resource
         TESTER.clickLink(
-        "body:content:body:container:content:tabbedPanel:panel:searchResult:outerObjectsRepeater:1"
+                "body:content:body:container:content:tabbedPanel:panel:searchResult:outerObjectsRepeater:1"
                 + ":outer:container:content:togglePanelContainer:container:actions:actions:actionRepeater:1:"
                 + "action:action");
 
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/DisplayAttributesITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/DisplayAttributesITCase.java
index 64c0856..dbce025 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/DisplayAttributesITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/DisplayAttributesITCase.java
@@ -52,8 +52,7 @@ public class DisplayAttributesITCase extends AbstractConsoleITCase {
         TESTER.clickLink(
                 "body:content:body:container:content:tabbedPanel:panel:searchResult:outerObjectsRepeater:"
                 + "3:outer:dialog:footer:inputs:0:submit");
-        TESTER.assertInfoMessages("Operation successfully executed");
-
+        assertSuccessMessage();
         TESTER.clearFeedbackMessages();
     }
 }
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/GroupsITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/GroupsITCase.java
index 2f63c75..7601f5e 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/GroupsITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/GroupsITCase.java
@@ -100,7 +100,7 @@ public class GroupsITCase extends AbstractConsoleITCase {
         assertNotNull(component);
 
         TESTER.executeAjaxEvent(component.getPageRelativePath(), Constants.ON_CLICK);
-        TESTER.clickLink(TAB_PANEL 
+        TESTER.clickLink(TAB_PANEL
                 + "outerObjectsRepeater:1:outer:container:content:togglePanelContainer:container:"
                 + "actions:actions:actionRepeater:9:action:action");
 
@@ -114,7 +114,7 @@ public class GroupsITCase extends AbstractConsoleITCase {
         formTester.setValue("view:name:textField", group + "_clone");
         formTester.submit("buttons:finish");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         TESTER.clickLink(TAB_PANEL
@@ -143,7 +143,7 @@ public class GroupsITCase extends AbstractConsoleITCase {
                 + "outerObjectsRepeater:1:outer:container:content:togglePanelContainer:container:"
                 + "actions:actions:actionRepeater:10:action:action"), Constants.ON_CLICK);
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
     }
 
@@ -215,7 +215,7 @@ public class GroupsITCase extends AbstractConsoleITCase {
         assertNotNull(formTester);
         formTester.submit("buttons:finish");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         TESTER.assertComponent(TAB_PANEL
@@ -239,7 +239,7 @@ public class GroupsITCase extends AbstractConsoleITCase {
                 + "outerObjectsRepeater:1:outer:container:content:togglePanelContainer:container:"
                 + "actions:actions:actionRepeater:10:action:action"), Constants.ON_CLICK);
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
     }
 
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/LogsITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/LogsITCase.java
index 6344e5c..281d714 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/LogsITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/LogsITCase.java
@@ -70,7 +70,7 @@ public class LogsITCase extends AbstractConsoleITCase {
         TESTER.executeAjaxEvent(
                 result.getPageRelativePath() + ":fields:1:field:dropDownChoiceField", Constants.ON_CHANGE);
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
     }
 
     @Test
@@ -98,7 +98,7 @@ public class LogsITCase extends AbstractConsoleITCase {
         TESTER.executeAjaxEvent(
                 result.getPageRelativePath() + ":fields:1:field:dropDownChoiceField", Constants.ON_CHANGE);
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
     }
 
     private static Component searchLog(final String property, final String searchPath, final String key) {
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/NotificationsITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/NotificationsITCase.java
index d447517..9dc050b 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/NotificationsITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/NotificationsITCase.java
@@ -108,8 +108,7 @@ public class NotificationsITCase extends AbstractConsoleITCase {
 
         TESTER.cleanupFeedbackMessages();
         formTester.submit("content:form:buttons:finish");
-        TESTER.assertInfoMessages("Operation successfully executed");
-
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
         TESTER.clickLink("body:configurationLI:configurationUL:notificationsLI:notifications");
     }
@@ -142,7 +141,7 @@ public class NotificationsITCase extends AbstractConsoleITCase {
                 "body:content:tabbedPanel:panel:outerObjectsRepeater:0:outer:form");
         formTester.submit("content:form:buttons:finish");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
     }
 
@@ -176,7 +175,7 @@ public class NotificationsITCase extends AbstractConsoleITCase {
                 + "firstLevelContainer:first:outerObjectsRepeater:1:outer:container:content:togglePanelContainer:"
                 + "container:actions:actions:actionRepeater:3:action:action");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         TESTER.clickLink("body:configurationLI:configurationUL:notificationsLI:notifications");
@@ -235,7 +234,7 @@ public class NotificationsITCase extends AbstractConsoleITCase {
                 + "togglePanelContainer:container:actions:actions:actionRepeater:2:action:action"),
                 Constants.ON_CLICK);
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         assertNull(findComponentByProp("Subject", "body:content:tabbedPanel:panel:container:content:"
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/ParametersITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/ParametersITCase.java
index e2c3693..26fd172 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/ParametersITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/ParametersITCase.java
@@ -62,8 +62,7 @@ public class ParametersITCase extends AbstractConsoleITCase {
 
         formTester.submit("content:parametersCreateWizardPanel:form:buttons:finish");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
-
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
         TESTER.assertRenderedPage(Parameters.class);
     }
@@ -90,9 +89,9 @@ public class ParametersITCase extends AbstractConsoleITCase {
 
         formTester.submit("content:parametersCreateWizardPanel:form:buttons:finish");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
-
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
+
         TESTER.assertRenderedPage(Parameters.class);
     }
 
@@ -114,7 +113,7 @@ public class ParametersITCase extends AbstractConsoleITCase {
 
         formTester.submit("content:parametersCreateWizardPanel:form:buttons:finish");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         Component result = findComponentByProp(SCHEMA, "body:content:parametersPanel", "deleteParam");
@@ -124,7 +123,7 @@ public class ParametersITCase extends AbstractConsoleITCase {
         TESTER.clickLink("body:content:parametersPanel:outerObjectsRepeater:1:outer:container:content:"
                 + "togglePanelContainer:container:actions:actions:actionRepeater:1:action:action");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
     }
 }
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/PoliciesITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/PoliciesITCase.java
index 43ba620..ce22d51 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/PoliciesITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/PoliciesITCase.java
@@ -60,7 +60,7 @@ public class PoliciesITCase extends AbstractConsoleITCase {
         TESTER.clickLink(
                 "body:content:tabbedPanel:panel:outerObjectsRepeater:0:outer:dialog:footer:inputs:0:submit");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         closeCallBack(modal);
@@ -117,7 +117,7 @@ public class PoliciesITCase extends AbstractConsoleITCase {
         TESTER.clickLink(
                 "body:content:tabbedPanel:panel:outerObjectsRepeater:0:outer:dialog:footer:inputs:0:submit");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         closeCallBack(modal);
@@ -167,7 +167,7 @@ public class PoliciesITCase extends AbstractConsoleITCase {
                 "body:content:tabbedPanel:panel:outerObjectsRepeater:0:outer:dialog:footer:inputs:0:submit",
                 Constants.ON_CLICK);
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         closeCallBack(modal);
@@ -214,7 +214,7 @@ public class PoliciesITCase extends AbstractConsoleITCase {
                 + "togglePanelContainer:container:actions:actions:actionRepeater:3:action:action"),
                 Constants.ON_CLICK);
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         assertNull(findComponentByProp("description", "body:content:tabbedPanel:panel:container:content:"
@@ -239,7 +239,7 @@ public class PoliciesITCase extends AbstractConsoleITCase {
                 + "togglePanelContainer:container:actions:actions:actionRepeater:3:action:action"),
                 Constants.ON_CLICK);
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         assertNull(findComponentByProp("description", "body:content:tabbedPanel:panel:container:content:"
@@ -264,7 +264,7 @@ public class PoliciesITCase extends AbstractConsoleITCase {
                 + "togglePanelContainer:container:actions:actions:actionRepeater:3:action:action"),
                 Constants.ON_CLICK);
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         assertNull(findComponentByProp("description", "body:content:tabbedPanel:panel:container:content:"
@@ -312,7 +312,7 @@ public class PoliciesITCase extends AbstractConsoleITCase {
         TESTER.clickLink(
                 "body:content:tabbedPanel:panel:outerObjectsRepeater:0:outer:dialog:footer:inputs:0:submit");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         closeCallBack(modal);
@@ -363,7 +363,7 @@ public class PoliciesITCase extends AbstractConsoleITCase {
         TESTER.clickLink(
                 "body:content:tabbedPanel:panel:outerObjectsRepeater:0:outer:dialog:footer:inputs:0:submit");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         closeCallBack(modal);
@@ -414,7 +414,7 @@ public class PoliciesITCase extends AbstractConsoleITCase {
         TESTER.clickLink(
                 "body:content:tabbedPanel:panel:outerObjectsRepeater:0:outer:dialog:footer:inputs:0:submit");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         closeCallBack(modal);
@@ -458,7 +458,7 @@ public class PoliciesITCase extends AbstractConsoleITCase {
         TESTER.clickLink(
                 "body:content:tabbedPanel:panel:outerObjectsRepeater:0:outer:dialog:footer:inputs:0:submit");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         closeCallBack(modal);
@@ -515,7 +515,7 @@ public class PoliciesITCase extends AbstractConsoleITCase {
                 + "outer:form:content:container:content:wizard:form");
         formTester.submit("buttons:finish");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         TESTER.clickLink(
@@ -560,7 +560,7 @@ public class PoliciesITCase extends AbstractConsoleITCase {
         TESTER.clickLink(
                 "body:content:tabbedPanel:panel:outerObjectsRepeater:0:outer:dialog:footer:inputs:0:submit");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         closeCallBack(modal);
@@ -621,7 +621,7 @@ public class PoliciesITCase extends AbstractConsoleITCase {
                 + "outer:form:content:container:content:wizard:form");
         formTester.submit("buttons:finish");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         TESTER.clickLink(
@@ -660,7 +660,7 @@ public class PoliciesITCase extends AbstractConsoleITCase {
         TESTER.clickLink(
                 "body:content:tabbedPanel:panel:outerObjectsRepeater:0:outer:dialog:footer:inputs:0:submit");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         closeCallBack(modal);
@@ -728,7 +728,7 @@ public class PoliciesITCase extends AbstractConsoleITCase {
         TESTER.clickLink(
                 "body:content:tabbedPanel:panel:outerObjectsRepeater:5:outer:dialog:footer:inputs:0:submit");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         closeCallBack(modal);
@@ -762,7 +762,7 @@ public class PoliciesITCase extends AbstractConsoleITCase {
         formTester.select("view:details:container:accountPolicy:dropDownChoiceField", 0);
         formTester.submit("buttons:finish");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         TESTER.executeAjaxEvent(
@@ -815,7 +815,7 @@ public class PoliciesITCase extends AbstractConsoleITCase {
         formTester.setValue("view:plainSchemas:tabs:0:body:content:schemas:14:panel:textField", "ross1030@apace.org");
         formTester.submit("buttons:finish");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         TESTER.clickLink("body:content:body:container:content:tabbedPanel:panel:searchResult:"
@@ -840,7 +840,7 @@ public class PoliciesITCase extends AbstractConsoleITCase {
                 + "1:outer:container:content:togglePanelContainer:container:actions:actions:actionRepeater:10:"
                 + "action:action"), Constants.ON_CLICK);
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         component = findComponentByProp("username",
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RealmsITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RealmsITCase.java
index 1870d49..fb2e3e1 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RealmsITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RealmsITCase.java
@@ -57,7 +57,7 @@ public class RealmsITCase extends AbstractConsoleITCase {
 
         formTester.submit("buttons:finish");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         TESTER.executeAjaxEvent(
@@ -79,7 +79,7 @@ public class RealmsITCase extends AbstractConsoleITCase {
         TESTER.clickLink(
                 "body:content:body:container:content:tabbedPanel:panel:actions:actions:actionRepeater:3:action:action");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         TESTER.assertLabel(
@@ -99,7 +99,7 @@ public class RealmsITCase extends AbstractConsoleITCase {
                 "body:content:body:outerObjectsRepeater:0:outer:form:content:form");
         formTester.submit("buttons:finish");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         TESTER.executeAjaxEvent(
@@ -133,7 +133,7 @@ public class RealmsITCase extends AbstractConsoleITCase {
         formTester.setValue("view:username:textField", "'k' + firstname");
         formTester.submit("buttons:finish");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         TESTER.assertLabel("body:content:realmChoicePanel:container:realm", "/odd");
@@ -156,7 +156,7 @@ public class RealmsITCase extends AbstractConsoleITCase {
         formTester.setValue("view:username:textField", "");
         formTester.submit("buttons:finish");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
     }
 
@@ -181,7 +181,7 @@ public class RealmsITCase extends AbstractConsoleITCase {
 
         formTester.submit("buttons:finish");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         // ----------------------------------
@@ -234,7 +234,7 @@ public class RealmsITCase extends AbstractConsoleITCase {
 
         formTester.submit("buttons:finish");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         // ----------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RelationshipTypesITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RelationshipTypesITCase.java
index 9f98d4b..13b08fa 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RelationshipTypesITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RelationshipTypesITCase.java
@@ -84,7 +84,7 @@ public class RelationshipTypesITCase extends AbstractTypesITCase {
 
         TESTER.clickLink(
                 "body:content:tabbedPanel:panel:outerObjectsRepeater:0:outer:dialog:footer:inputs:0:submit");
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
     }
 
     @Test
@@ -109,7 +109,7 @@ public class RelationshipTypesITCase extends AbstractTypesITCase {
                 "body:content:tabbedPanel:panel:outerObjectsRepeater:1:outer:container:content:"
                 + "togglePanelContainer:container:actions:actions:actionRepeater:1:action:action"), Constants.ON_CLICK);
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
 
         TESTER.cleanupFeedbackMessages();
         result = findComponentByProp(KEY, DATATABLE_PATH, name);
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/ReportsITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/ReportsITCase.java
index c12f2ba..04e1a5d 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/ReportsITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/ReportsITCase.java
@@ -60,7 +60,7 @@ public class ReportsITCase extends AbstractConsoleITCase {
                 "body:content:tabbedPanel:panel:firstLevelContainer:first:outerObjectsRepeater:0:outer:form");
         formTester.submit("content:form:buttons:finish");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         TESTER.clickLink("body:reportsLI:reports");
@@ -86,7 +86,7 @@ public class ReportsITCase extends AbstractConsoleITCase {
                 + "container:content:togglePanelContainer:container:actions:actions:actionRepeater:5:action:action"),
                 Constants.ON_CLICK);
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         assertNull(findComponentByProp(
@@ -158,7 +158,7 @@ public class ReportsITCase extends AbstractConsoleITCase {
                 "body:content:tabbedPanel:panel:firstLevelContainer:first:outerObjectsRepeater:0:outer:form");
         formTester.submit("content:form:buttons:finish");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         delete("updateReport");
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RolesITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RolesITCase.java
index ade1a0b..c3d350d 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RolesITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RolesITCase.java
@@ -67,7 +67,7 @@ public class RolesITCase extends AbstractConsoleITCase {
                 "body:content:tabbedPanel:panel:outerObjectsRepeater:0:outer:form");
         formTester.submit("content:form:buttons:finish");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         TESTER.clickLink("body:configurationLI:configurationUL:securityLI:security");
@@ -133,7 +133,7 @@ public class RolesITCase extends AbstractConsoleITCase {
                 "body:content:tabbedPanel:panel:outerObjectsRepeater:0:outer:form");
         formTester.submit("content:form:buttons:finish");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
     }
 
@@ -157,7 +157,7 @@ public class RolesITCase extends AbstractConsoleITCase {
                 "body:content:tabbedPanel:panel:outerObjectsRepeater:1:outer:container:content:togglePanelContainer:"
                 + "container:actions:actions:actionRepeater:4:action:action"), "onclick");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         assertNull(findComponentByProp(KEY,
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/SchemasITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/SchemasITCase.java
index f10207e..090987d 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/SchemasITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/SchemasITCase.java
@@ -75,7 +75,7 @@ public class SchemasITCase extends AbstractTypesITCase {
                 + "accordionPanel:tabs:0:body:content:outerObjectsRepeater:0:outer:form");
         formTester.submit("content:form:buttons:finish");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
 
         TESTER.cleanupFeedbackMessages();
         TESTER.assertRenderedPage(Types.class);
@@ -111,7 +111,7 @@ public class SchemasITCase extends AbstractTypesITCase {
                 + "accordionPanel:tabs:0:body:content:outerObjectsRepeater:0:outer:form");
         formTester.submit("content:form:buttons:finish");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
     }
 
     @Test
@@ -137,7 +137,7 @@ public class SchemasITCase extends AbstractTypesITCase {
                 + "accordionPanel:tabs:0:body:content:outerObjectsRepeater:0:outer:form");
         formTester.submit("content:form:buttons:finish");
 
-        TESTER.assertInfoMessages("Operation successfully executed");;
+        assertSuccessMessage();
 
         TESTER.cleanupFeedbackMessages();
 
@@ -163,7 +163,7 @@ public class SchemasITCase extends AbstractTypesITCase {
                 + "container:content:togglePanelContainer:container:actions:actions:actionRepeater:1:action:action"),
                 Constants.ON_CLICK);
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         assertNull(findComponentByProp(KEY, PLAIN_DATATABLE_PATH, schemaName));
@@ -199,7 +199,7 @@ public class SchemasITCase extends AbstractTypesITCase {
                 + "accordionPanel:tabs:2:body:content:outerObjectsRepeater:0:outer:form");
         formTester.submit("content:form:buttons:finish");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
         TESTER.assertRenderedPage(Types.class);
 
@@ -216,7 +216,7 @@ public class SchemasITCase extends AbstractTypesITCase {
                 + "container:content:togglePanelContainer:container:actions:actions:actionRepeater:1:action:action"),
                 Constants.ON_CLICK);
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         assertNull(findComponentByProp(KEY, VIRTUAL_DATATABLE_PATH, "mynewvir"));
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/SecurityQuestionsITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/SecurityQuestionsITCase.java
index 168b70e..329369e 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/SecurityQuestionsITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/SecurityQuestionsITCase.java
@@ -56,7 +56,7 @@ public class SecurityQuestionsITCase extends AbstractConsoleITCase {
         TESTER.clickLink(
                 "body:content:tabbedPanel:panel:outerObjectsRepeater:0:outer:dialog:footer:inputs:0:submit");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         TESTER.clickLink("body:configurationLI:configurationUL:securityLI:security");
@@ -107,7 +107,7 @@ public class SecurityQuestionsITCase extends AbstractConsoleITCase {
         TESTER.clickLink(
                 "body:content:tabbedPanel:panel:outerObjectsRepeater:0:outer:dialog:footer:inputs:0:submit");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
     }
 
@@ -131,7 +131,7 @@ public class SecurityQuestionsITCase extends AbstractConsoleITCase {
                 "body:content:tabbedPanel:panel:outerObjectsRepeater:1:outer:container:content:"
                 + "togglePanelContainer:container:actions:actions:actionRepeater:1:action:action"), "onclick");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         assertNull(findComponentByProp("content",
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/TopologyITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/TopologyITCase.java
index 247ef5e..6e1e142 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/TopologyITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/TopologyITCase.java
@@ -181,7 +181,7 @@ public class TopologyITCase extends AbstractConsoleITCase {
         // ajax event required to retrieve AjaxRequestTarget (used into finish custom event)
         TESTER.executeAjaxEvent(
                 "body:toggle:outerObjectsRepeater:0:outer:form:content:form:buttons:finish", Constants.ON_CLICK);
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
 
         TESTER.cleanupFeedbackMessages();
         TESTER.clickLink("body:idmPages:0:idmPageLI:idmPage");
@@ -245,7 +245,7 @@ public class TopologyITCase extends AbstractConsoleITCase {
         TESTER.executeAjaxEvent(
                 "body:toggle:outerObjectsRepeater:3:outer:form:content:provision:container:"
                 + "content:wizard:form:buttons:finish", Constants.ON_CLICK);
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
 
         TESTER.assertComponent(
                 "body:toggle:outerObjectsRepeater:3:outer:dialog:footer:inputs:0:submit", AjaxSubmitLink.class);
@@ -255,7 +255,7 @@ public class TopologyITCase extends AbstractConsoleITCase {
         TESTER.executeAjaxEvent(
                 "body:toggle:outerObjectsRepeater:3:outer:dialog:footer:inputs:0:submit", Constants.ON_CLICK);
         TESTER.assertNoErrorMessage();
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
 
         TESTER.executeAjaxEvent(
                 "body:toggle:outerObjectsRepeater:3:outer:form:content:provision:container:"
@@ -286,7 +286,7 @@ public class TopologyITCase extends AbstractConsoleITCase {
         TESTER.getRequest().addParameter("confirm", "true");
         TESTER.clickLink("body:toggle:container:content:togglePanelContainer:container:actions:delete");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         TESTER.clickLink("body:idmPages:0:idmPageLI:idmPage");
@@ -315,7 +315,7 @@ public class TopologyITCase extends AbstractConsoleITCase {
         TESTER.clickLink(
                 "body:toggle:outerObjectsRepeater:2:outer:form:content:tasks:firstLevelContainer:first:"
                 + "container:content:startAt:container:content:togglePanelContainer:startAtForm:startAt");
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
 
         component = findComponentByProp("name",
                 "body:toggle:outerObjectsRepeater:2:outer:form:content:tasks:"
@@ -469,7 +469,7 @@ public class TopologyITCase extends AbstractConsoleITCase {
                 + "tasks:firstLevelContainer:first:container:content:wizard:form");
         formTester.submit("buttons:finish");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
     }
 
@@ -536,13 +536,13 @@ public class TopologyITCase extends AbstractConsoleITCase {
         formTester.setValue("view:name:textField", "'k' + name");
         formTester.submit("buttons:finish");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         TESTER.executeAjaxEvent(
                 "body:toggle:outerObjectsRepeater:2:outer:form:content:tasks:firstLevelContainer:"
                 + "first:container:content:searchContainer:resultTable:tablePanel:groupForm:checkgroup:dataTable:"
-                + "body:rows:1", Constants.ON_CLICK);
+                + "body:rows:2", Constants.ON_CLICK);
         TESTER.clickLink(
                 "body:toggle:outerObjectsRepeater:2:outer:form:content:tasks:firstLevelContainer:first:"
                 + "outerObjectsRepeater:1:outer:container:content:togglePanelContainer:container:"
@@ -574,7 +574,7 @@ public class TopologyITCase extends AbstractConsoleITCase {
         formTester.setValue("view:name:textField", "");
         formTester.submit("buttons:finish");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
     }
 
@@ -589,7 +589,7 @@ public class TopologyITCase extends AbstractConsoleITCase {
         TESTER.getRequest().addParameter("confirm", "true");
         TESTER.clickLink("body:toggle:container:content:togglePanelContainer:container:actions:reload");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
     }
 }
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/UsersITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/UsersITCase.java
index 04fa209..3359785 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/UsersITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/UsersITCase.java
@@ -80,7 +80,7 @@ public class UsersITCase extends AbstractConsoleITCase {
                 + "outerObjectsRepeater:1:outer:container:content:togglePanelContainer:container:"
                 + "actions:actions:actionRepeater:1:action:action");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
     }
 
     @Test
@@ -240,7 +240,7 @@ public class UsersITCase extends AbstractConsoleITCase {
         assertNotNull(formTester);
         formTester.submit("buttons:finish");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
 
         TESTER.assertComponent(TAB_PANEL
                 + "outerObjectsRepeater:0:outer:form:content:customResultBody:resources:firstLevelContainer:first:"
@@ -310,7 +310,7 @@ public class UsersITCase extends AbstractConsoleITCase {
         assertNotNull(formTester);
         formTester.submit("buttons:finish");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         TESTER.assertComponent(TAB_PANEL
@@ -344,7 +344,7 @@ public class UsersITCase extends AbstractConsoleITCase {
         TESTER.executeAjaxEvent(
                 TAB_PANEL + "outerObjectsRepeater:0:outer:form:content:form:buttons:finish", Constants.ON_CLICK);
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
     }
 
@@ -426,7 +426,7 @@ public class UsersITCase extends AbstractConsoleITCase {
         assertNotNull(formTester);
         formTester.submit("buttons:finish");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         TESTER.assertComponent(TAB_PANEL
@@ -509,7 +509,7 @@ public class UsersITCase extends AbstractConsoleITCase {
         assertNotNull(formTester);
         formTester.submit("buttons:finish");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         TESTER.assertComponent(TAB_PANEL
@@ -626,7 +626,7 @@ public class UsersITCase extends AbstractConsoleITCase {
 
         formTester.submit("buttons:finish");
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         TESTER.assertComponent(TAB_PANEL
@@ -708,7 +708,7 @@ public class UsersITCase extends AbstractConsoleITCase {
         TESTER.executeAjaxEvent(
                 TAB_PANEL + "outerObjectsRepeater:3:outer:dialog:footer:inputs:0:submit", Constants.ON_CLICK);
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
 
         TESTER.clickLink("body:realmsLI:realms");
@@ -734,7 +734,7 @@ public class UsersITCase extends AbstractConsoleITCase {
         TESTER.executeAjaxEvent(
                 TAB_PANEL + "outerObjectsRepeater:3:outer:dialog:footer:inputs:0:submit", Constants.ON_CLICK);
 
-        TESTER.assertInfoMessages("Operation successfully executed");
+        assertSuccessMessage();
         TESTER.cleanupFeedbackMessages();
     }
 }
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/ui/AbstractUITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/ui/AbstractUITCase.java
index 8b06c6c..4fc469c 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/ui/AbstractUITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/ui/AbstractUITCase.java
@@ -18,13 +18,20 @@
  */
 package org.apache.syncope.fit.ui;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
 import java.io.Serializable;
 import java.lang.reflect.Method;
+import java.util.Set;
+import java.util.stream.Collectors;
 import org.apache.syncope.common.rest.api.service.SyncopeService;
 import org.apache.wicket.Component;
 import org.apache.wicket.MarkupContainer;
 import org.apache.wicket.behavior.AbstractAjaxBehavior;
 import org.apache.wicket.core.util.lang.PropertyResolver;
+import org.apache.wicket.feedback.ExactLevelFeedbackMessageFilter;
+import org.apache.wicket.feedback.FeedbackMessage;
 import org.apache.wicket.markup.html.list.ListItem;
 import org.apache.wicket.util.tester.WicketTester;
 import org.apache.wicket.util.visit.IVisit;
@@ -108,4 +115,14 @@ public abstract class AbstractUITCase {
                 filter(behavior -> (behavior instanceof AbstractAjaxBehavior)).
                 forEachOrdered(behavior -> TESTER.executeBehavior((AbstractAjaxBehavior) behavior));
     }
+
+    protected static void assertSuccessMessage() {
+        Set<Serializable> messages =
+                TESTER.getFeedbackMessages(new ExactLevelFeedbackMessageFilter(FeedbackMessage.INFO)).stream().
+                        map(FeedbackMessage::getMessage).collect(Collectors.toSet());
+        if (messages.size() != 1) {
+            fail("Expected single message but found " + messages);
+        }
+        assertEquals("Operation successfully executed", messages.iterator().next());
+    }
 }