commit 42d326df479a2586bd2e8350fb04a2180f5c1a64
Author: Andreas Kohlbecker <a.kohlbecker@bgbm.org>
Date:   Mon Mar 19 11:37:13 2018 +0100

    ref #7241 DelegatingErrorHandler more generically

diff --git a/src/main/java/eu/etaxonomy/cdm/vaadin/event/error/DelegatingErrorHandler.java b/src/main/java/eu/etaxonomy/cdm/vaadin/event/error/DelegatingErrorHandler.java
index 3a9d4acf..6e2c14cb 100644
--- a/src/main/java/eu/etaxonomy/cdm/vaadin/event/error/DelegatingErrorHandler.java
+++ b/src/main/java/eu/etaxonomy/cdm/vaadin/event/error/DelegatingErrorHandler.java
@@ -1,4 +1,3 @@
-// $Id$
 /**
 * Copyright (C) 2018 EDIT
 * European Distributed Institute of Taxonomy
@@ -9,8 +8,8 @@
 */
 package eu.etaxonomy.cdm.vaadin.event.error;
 
-import java.util.HashMap;
-import java.util.Map;
+import java.util.HashSet;
+import java.util.Set;
 
 import org.apache.log4j.Logger;
 
@@ -26,17 +25,28 @@ import com.vaadin.ui.Notification;
  * see https://dev.e-taxonomy.eu/redmine/issues/7241
  *
  * @author freimeier
- * @date 26.02.2018
  *
  */
 public class DelegatingErrorHandler implements ErrorHandler{
 
     private static final long serialVersionUID = 3378605204517477112L;
 
-    Map<Class<? extends Exception>, ErrorTypeHandler<? extends Exception>> handlerMap = new HashMap<>();
+    Set<ErrorTypeHandler<? extends Throwable>> handlers = new HashSet<>();
+
+    public <E extends Throwable> void  registerHandler(ErrorTypeHandler<E> handler) {
+        assert findHandler(handler.supports()) == null;
+        handlers.add(handler);
+    }
+
+    @SuppressWarnings("unchecked")
+    public <E extends Throwable> ErrorTypeHandler<E> findHandler(Class<E> errorClass){
+        for(ErrorTypeHandler<?> h : handlers){
+            if(h.supports().equals(errorClass)){
+                return (ErrorTypeHandler<E>) h;
+            }
+        }
+        return null;
 
-    public <E extends Exception> void  registerHandler(Class<E> type, ErrorTypeHandler<E> handler) {
-        handlerMap.put(type, handler);
     }
 
     /* (non-Javadoc)
@@ -45,12 +55,27 @@ public class DelegatingErrorHandler implements ErrorHandler{
     @Override
     public void error(ErrorEvent event) {
 
-        Class<? extends Throwable> errorClass = event.getThrowable().getCause().getClass();
-        Logger.getLogger(this.getClass()).debug(errorClass);
-        if(handlerMap.get(errorClass) != null){
-            handlerMap.get(errorClass).error(event);
-          } else {
+        boolean handlerFound = true;
+        Throwable throwable = event.getThrowable();
+        while(throwable != null){
+            if(delegate(event, throwable)){
+                break;
+            }
+            throwable = throwable.getCause();
+        }
+        if(!handlerFound){
             Notification.show(event.getThrowable().getMessage());
           }
     }
+
+    private <E extends Throwable> boolean delegate(ErrorEvent event, E throwable){
+        Class<E> errorClass = (Class<E>) throwable.getClass();
+        Logger.getLogger(this.getClass()).debug(errorClass);
+        ErrorTypeHandler<E> handler = findHandler(errorClass);
+        if(handler != null){
+            handler.handleError(event, throwable);
+            return true;
+        }
+        return false;
+    }
 }
diff --git a/src/main/java/eu/etaxonomy/cdm/vaadin/event/error/ErrorTypeHandler.java b/src/main/java/eu/etaxonomy/cdm/vaadin/event/error/ErrorTypeHandler.java
index 516bae17..70a0a2c0 100644
--- a/src/main/java/eu/etaxonomy/cdm/vaadin/event/error/ErrorTypeHandler.java
+++ b/src/main/java/eu/etaxonomy/cdm/vaadin/event/error/ErrorTypeHandler.java
@@ -1,4 +1,3 @@
-// $Id$
 /**
 * Copyright (C) 2018 EDIT
 * European Distributed Institute of Taxonomy
@@ -16,23 +15,23 @@ import com.vaadin.server.ErrorHandler;
  * see {@link DelegatingErrorHandler}
  *
  * @author freimeier
- * @date 26.02.2018
  *
  */
-public abstract class ErrorTypeHandler<E extends Exception> implements ErrorHandler {
+public abstract class ErrorTypeHandler<E extends Throwable> implements ErrorHandler {
 
-    private static final long serialVersionUID = 1782060185842059311L;
+    private  static final long serialVersionUID = 1782060185842059311L;
 
-    /* (non-Javadoc)
-     * @see com.vaadin.server.ErrorHandler#error(com.vaadin.server.ErrorEvent)
-     */
-    @Override
-    public final void error(ErrorEvent event) {
-        handleError((E) event.getThrowable().getCause());
+    public abstract Class<E> supports();
 
+    public final void handleError(ErrorEvent event, E throwable){
+        error(event);
+        exception(throwable);
     }
 
-    public abstract void handleError(E exception);
+    /**
+     * @param exception
+     */
+    public abstract void exception(E throwable);
 }
 
 
diff --git a/src/main/java/eu/etaxonomy/cdm/vaadin/event/error/ExternalServiceExceptionHandler.java b/src/main/java/eu/etaxonomy/cdm/vaadin/event/error/ExternalServiceExceptionHandler.java
new file mode 100644
index 00000000..79dd5c86
--- /dev/null
+++ b/src/main/java/eu/etaxonomy/cdm/vaadin/event/error/ExternalServiceExceptionHandler.java
@@ -0,0 +1,61 @@
+/**
+* Copyright (C) 2018 EDIT
+* European Distributed Institute of Taxonomy
+* http://www.e-taxonomy.eu
+*
+* The contents of this file are subject to the Mozilla Public License Version 1.1
+* See LICENSE.TXT at the top of this package for the full license terms.
+*/
+package eu.etaxonomy.cdm.vaadin.event.error;
+
+import com.vaadin.server.ErrorEvent;
+import com.vaadin.server.Page;
+import com.vaadin.ui.Notification;
+import com.vaadin.ui.Notification.Type;
+
+import eu.etaxonomy.cdm.ext.common.ExternalServiceException;
+import eu.etaxonomy.cdm.vaadin.ui.RegistrationUIDefaults;
+
+
+public class ExternalServiceExceptionHandler extends ErrorTypeHandler<ExternalServiceException>{
+
+    private static final long serialVersionUID = -5703485298578474572L;
+    private String mainMessage;
+
+    public ExternalServiceExceptionHandler(String mainMessage){
+        this.mainMessage = mainMessage;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Class<ExternalServiceException> supports() {
+        return ExternalServiceException.class;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void error(ErrorEvent event) {
+        // only exception() needed in this class
+
+    }
+
+    @Override
+    public void exception(ExternalServiceException exception) {
+        Notification notification = new Notification(mainMessage,
+                "<div><strong>Service:</strong> "+ exception.getExternalService() + "</div>" +
+                "<div><strong>Problem:</strong> "+ exception.getProblem() + "</div>" +
+                "<p>" + RegistrationUIDefaults.ERROR_CONTACT_MESSAGE_LINE + "</p>"
+                , Type.ERROR_MESSAGE);
+        notification.setHtmlContentAllowed(true);
+        notification.show(Page.getCurrent());
+    }
+
+
+
+}
diff --git a/src/main/java/eu/etaxonomy/cdm/vaadin/event/error/HibernateSystemErrorHandler.java b/src/main/java/eu/etaxonomy/cdm/vaadin/event/error/HibernateSystemErrorHandler.java
index b9b6da63..821cab93 100644
--- a/src/main/java/eu/etaxonomy/cdm/vaadin/event/error/HibernateSystemErrorHandler.java
+++ b/src/main/java/eu/etaxonomy/cdm/vaadin/event/error/HibernateSystemErrorHandler.java
@@ -11,6 +11,7 @@ package eu.etaxonomy.cdm.vaadin.event.error;
 
 import org.springframework.orm.hibernate5.HibernateSystemException;
 
+import com.vaadin.server.ErrorEvent;
 import com.vaadin.ui.Notification;
 
 import eu.etaxonomy.cdm.database.PermissionDeniedException;
@@ -18,18 +19,31 @@ import eu.etaxonomy.cdm.i18n.Messages;
 
 /**
  * @author freimeier
- * @date 26.02.2018
  *
  */
 public class HibernateSystemErrorHandler extends ErrorTypeHandler<HibernateSystemException>{
 
     private static final long serialVersionUID = -5703485298578474572L;
 
-    /* (non-Javadoc)
-     * @see eu.etaxonomy.cdm.vaadin.util.errorhandler.ErrorTypeHandler#handleError(com.vaadin.server.ErrorEvent)
+    /**
+     * {@inheritDoc}
      */
     @Override
-    public void handleError(HibernateSystemException exception) {
+    public Class<HibernateSystemException> supports() {
+        return HibernateSystemException.class;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void error(ErrorEvent event) {
+        // not needed in this class so far
+    }
+
+    @Override
+    public void exception(HibernateSystemException exception) {
+
         if(exception != null) {
             if(exception.getCause().getClass().equals(PermissionDeniedException.class)) {
                 Notification.show(Messages.getLocalizedString(Messages.PermissionDeniedErrorHandler_ERROR_MSG));
@@ -39,4 +53,6 @@ public class HibernateSystemErrorHandler extends ErrorTypeHandler<HibernateSyste
         }
     }
 
+
+
 }
diff --git a/src/main/java/eu/etaxonomy/cdm/vaadin/view/distributionStatus/DistributionTableViewBean.java b/src/main/java/eu/etaxonomy/cdm/vaadin/view/distributionStatus/DistributionTableViewBean.java
index 365b050a..9b278912 100644
--- a/src/main/java/eu/etaxonomy/cdm/vaadin/view/distributionStatus/DistributionTableViewBean.java
+++ b/src/main/java/eu/etaxonomy/cdm/vaadin/view/distributionStatus/DistributionTableViewBean.java
@@ -16,7 +16,6 @@ import java.util.List;
 import java.util.UUID;
 
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.orm.hibernate5.HibernateSystemException;
 import org.springframework.security.core.GrantedAuthority;
 import org.vaadin.addons.lazyquerycontainer.LazyQueryContainer;
 
@@ -175,7 +174,7 @@ public class DistributionTableViewBean
                 //popup window
                 final Window popup = new Window(Messages.getLocalizedString(Messages.DistributionTableViewBean_CHOOSE_DISTRIBUTION_STATUS));
                 DelegatingErrorHandler errorHandler = new DelegatingErrorHandler();
-                errorHandler.registerHandler(HibernateSystemException.class, new HibernateSystemErrorHandler());
+                errorHandler.registerHandler(new HibernateSystemErrorHandler());
                 popup.setErrorHandler(errorHandler);
                 final ListSelect termSelect = new ListSelect();
                 termSelect.setSizeFull();
