diff --git a/src/main/java/sh/libre/scim/core/AbstractScimService.java b/src/main/java/sh/libre/scim/core/AbstractScimService.java
index 637283c0431a6c217d666ae5c2b36c1b6d17f61a..b72bef678d13d07ab7308901bff5a91ce018ad2b 100644
--- a/src/main/java/sh/libre/scim/core/AbstractScimService.java
+++ b/src/main/java/sh/libre/scim/core/AbstractScimService.java
@@ -82,10 +82,12 @@ public abstract class AbstractScimService<RMM extends RoleMapperModel, S extends
             entityOnRemoteScimId
                     .ifPresentOrElse(
                             externalId -> doReplace(roleMapperModel, externalId),
-                            () -> LOGGER.warnf("failed to replace resource %s, scim mapping not found", id)
+                            () -> {
+                                // TODO Exception Handling : should we throw a ScimPropagationException here ?
+                                LOGGER.warnf("failed to replace resource %s, scim mapping not found", id);
+                            }
                     );
         } catch (Exception e) {
-            LOGGER.error(e);
             throw new ScimPropagationException("[SCIM] Error while replacing SCIM resource", e);
         }
     }
@@ -106,21 +108,21 @@ public abstract class AbstractScimService<RMM extends RoleMapperModel, S extends
     }
 
     public void refreshResources(SynchronizationResult syncRes) throws ScimPropagationException {
-        LOGGER.info("Refresh resources");
+        LOGGER.info("[SCIM] Refresh resources for endpoint  " + this.getConfiguration().getEndPoint());
         try (Stream<RMM> resourcesStream = getResourceStream()) {
             Set<RMM> resources = resourcesStream.collect(Collectors.toUnmodifiableSet());
             for (RMM resource : resources) {
                 KeycloakId id = getId(resource);
-                LOGGER.infof("Reconciling local resource %s", id);
+                LOGGER.infof("[SCIM] Reconciling local resource %s", id);
                 if (isSkipRefresh(resource)) {
-                    LOGGER.infof("Skip local resource %s", id);
+                    LOGGER.infof("[SCIM] Skip local resource %s", id);
                     continue;
                 }
                 if (findById(id).isPresent()) {
-                    LOGGER.info("Replacing it");
+                    LOGGER.info("[SCIM] Replacing it");
                     replace(resource);
                 } else {
-                    LOGGER.info("Creating it");
+                    LOGGER.info("[SCIM] Creating it");
                     create(resource);
                 }
                 syncRes.increaseUpdated();
@@ -133,11 +135,11 @@ public abstract class AbstractScimService<RMM extends RoleMapperModel, S extends
     protected abstract Stream<RMM> getResourceStream();
 
     public void importResources(SynchronizationResult syncRes) throws ScimPropagationException {
-        LOGGER.info("Import");
+        LOGGER.info("[SCIM] Import resources for scim endpoint " + this.getConfiguration().getEndPoint());
         try {
             for (S resource : scimClient.listResources()) {
                 try {
-                    LOGGER.infof("Reconciling remote resource %s", resource);
+                    LOGGER.infof("[SCIM] Reconciling remote resource %s", resource);
                     EntityOnRemoteScimId externalId = resource.getId()
                             .map(EntityOnRemoteScimId::new)
                             .orElseThrow(() -> new ScimPropagationException("remote SCIM resource doesn't have an id"));
@@ -145,49 +147,50 @@ public abstract class AbstractScimService<RMM extends RoleMapperModel, S extends
                     if (optionalMapping.isPresent()) {
                         ScimResource mapping = optionalMapping.get();
                         if (entityExists(mapping.getIdAsKeycloakId())) {
-                            LOGGER.info("Valid mapping found, skipping");
+                            LOGGER.info("[SCIM] Valid mapping found, skipping");
                             continue;
                         } else {
-                            LOGGER.info("Delete a dangling mapping");
+                            LOGGER.info("[SCIM] Delete a dangling mapping");
                             getScimResourceDao().delete(mapping);
                         }
                     }
 
                     Optional<KeycloakId> mapped = tryToMap(resource);
                     if (mapped.isPresent()) {
-                        LOGGER.info("Matched");
+                        LOGGER.info("[SCIM] Matched");
                         createMapping(mapped.get(), externalId);
                     } else {
                         switch (scimProviderConfiguration.getImportAction()) {
                             case CREATE_LOCAL:
-                                LOGGER.info("Create local resource");
+                                LOGGER.info("[SCIM] Create local resource");
                                 try {
                                     KeycloakId id = createEntity(resource);
                                     createMapping(id, externalId);
                                     syncRes.increaseAdded();
                                 } catch (Exception e) {
+                                    // TODO ExceptionHandling should we stop and throw ScimPropagationException here ?
                                     LOGGER.error(e);
                                 }
                                 break;
                             case DELETE_REMOTE:
-                                LOGGER.info("Delete remote resource");
+                                LOGGER.info("[SCIM] Delete remote resource");
                                 this.scimClient.delete(externalId);
                                 syncRes.increaseRemoved();
                                 break;
                             case NOTHING:
-                                LOGGER.info("Import action set to NOTHING");
+                                LOGGER.info("[SCIM] Import action set to NOTHING");
                                 break;
                         }
                     }
                 } catch (Exception e) {
-                    // TODO should we stop and throw ScimPropagationException here ?
+                    // TODO ExceptionHandling should we stop and throw ScimPropagationException here ?
                     LOGGER.error(e);
                     e.printStackTrace();
                     syncRes.increaseFailed();
                 }
             }
         } catch (ResponseException e) {
-            // TODO should we stop and throw ScimPropagationException here ?
+            // TODO ExceptionHandling should we stop and throw ScimPropagationException here ?
             LOGGER.error(e);
             e.printStackTrace();
             syncRes.increaseFailed();
diff --git a/src/main/java/sh/libre/scim/core/GroupScimService.java b/src/main/java/sh/libre/scim/core/GroupScimService.java
index e5b23155523e64d0aa27caba48b4c895b25630dc..c448a9a00a3bc1f8fc23bb6807403dd25b72dc53 100644
--- a/src/main/java/sh/libre/scim/core/GroupScimService.java
+++ b/src/main/java/sh/libre/scim/core/GroupScimService.java
@@ -20,7 +20,7 @@ import java.util.TreeSet;
 import java.util.stream.Stream;
 
 public class GroupScimService extends AbstractScimService<GroupModel, Group> {
-    private final Logger logger = Logger.getLogger(GroupScimService.class);
+    private final Logger LOGGER = Logger.getLogger(GroupScimService.class);
 
     public GroupScimService(KeycloakSession keycloakSession, ScrimProviderConfiguration scimProviderConfiguration) {
         super(keycloakSession, scimProviderConfiguration, ScimResourceType.GROUP);
@@ -95,13 +95,13 @@ public class GroupScimService extends AbstractScimService<GroupModel, Group> {
             if (optionalGroupMemberMapping.isPresent()) {
                 ScimResource groupMemberMapping = optionalGroupMemberMapping.get();
                 EntityOnRemoteScimId externalIdAsEntityOnRemoteScimId = groupMemberMapping.getExternalIdAsEntityOnRemoteScimId();
-                logger.debugf("found mapping for group member %s as %s", member, externalIdAsEntityOnRemoteScimId);
                 groupMember.setValue(externalIdAsEntityOnRemoteScimId.asString());
                 URI ref = getUri(ScimResourceType.USER, externalIdAsEntityOnRemoteScimId);
                 groupMember.setRef(ref.toString());
                 group.addMember(groupMember);
             } else {
-                logger.warnf("member %s not found for group %s", member, groupModel.getId());
+                // TODO Exception Handling : should we throw an exception when some group members can't be found ?
+                LOGGER.warnf("member %s not found for group %s", member, groupModel.getId());
             }
         }
         return group;
diff --git a/src/main/java/sh/libre/scim/core/ScimClient.java b/src/main/java/sh/libre/scim/core/ScimClient.java
index ea89c60415f091fcd9b24e0445ec90b6f32f3fbc..caa318a60cbfd2907969f876fada42ed5001d895 100644
--- a/src/main/java/sh/libre/scim/core/ScimClient.java
+++ b/src/main/java/sh/libre/scim/core/ScimClient.java
@@ -85,6 +85,7 @@ public class ScimClient<S extends ResourceNode> implements AutoCloseable {
 
     private void checkResponseIsSuccess(ServerResponse<S> response) {
         if (!response.isSuccess()) {
+            // TODO Exception handling : we should throw a SCIM Progagation exception here
             LOGGER.warn("[SCIM] Issue on SCIM Server response ");
             LOGGER.warn(response.getResponseBody());
             LOGGER.warn(response.getHttpStatus());
diff --git a/src/main/java/sh/libre/scim/core/ScimDispatcher.java b/src/main/java/sh/libre/scim/core/ScimDispatcher.java
index 54c484399848ab24ea50cc88310e42229381352a..2ec51aa924ddbd6b5b32fdafa6bac6a2cc00e83a 100644
--- a/src/main/java/sh/libre/scim/core/ScimDispatcher.java
+++ b/src/main/java/sh/libre/scim/core/ScimDispatcher.java
@@ -16,7 +16,7 @@ import java.util.Set;
  */
 public class ScimDispatcher {
 
-    private static final Logger logger = Logger.getLogger(ScimDispatcher.class);
+    private static final Logger LOGGER = Logger.getLogger(ScimDispatcher.class);
 
     private final KeycloakSession session;
     private final ScimExceptionHandler exceptionHandler;
@@ -34,42 +34,32 @@ public class ScimDispatcher {
      * Lists all active ScimStorageProviderFactory and create new ScimClients for each of them
      */
     public void refreshActiveScimEndpoints() {
-        try {
-            // Step 1: close existing clients
-            for (GroupScimService c : groupScimServices) {
-                c.close();
-            }
-            groupScimServices.clear();
-            for (UserScimService c : userScimServices) {
-                c.close();
-            }
-            userScimServices.clear();
-
-            // Step 2: Get All SCIM endpoints defined in Admin Console (enabled ScimStorageProviderFactory)
-            session.getContext().getRealm().getComponentsStream()
-                    .filter(m -> ScimEndpointConfigurationStorageProviderFactory.ID.equals(m.getProviderId())
-                                 && m.get("enabled", true))
-                    .forEach(scimEndpointConfigurationRaw -> {
-                        ScrimProviderConfiguration scrimProviderConfiguration = new ScrimProviderConfiguration(scimEndpointConfigurationRaw);
-                        try {
-                            // Step 3 : create scim clients for each endpoint
-                            if (scimEndpointConfigurationRaw.get(ScrimProviderConfiguration.CONF_KEY_PROPAGATION_GROUP, false)) {
-                                GroupScimService groupScimService = new GroupScimService(session, scrimProviderConfiguration);
-                                groupScimServices.add(groupScimService);
-                            }
-                            if (scimEndpointConfigurationRaw.get(ScrimProviderConfiguration.CONF_KEY_PROPAGATION_USER, false)) {
-                                UserScimService userScimService = new UserScimService(session, scrimProviderConfiguration);
-                                userScimServices.add(userScimService);
-                            }
-                        } catch (Exception e) {
-                            logger.warnf("[SCIM] Invalid Endpoint configuration %s: %s", scimEndpointConfigurationRaw.getId(), e.getMessage());
-                            // TODO is it ok to log and try to create the other clients ?
+        // Step 1: close existing clients (as configuration may have changed)
+        groupScimServices.forEach(GroupScimService::close);
+        groupScimServices.clear();
+        userScimServices.forEach(UserScimService::close);
+        userScimServices.clear();
+
+        // Step 2: Get All SCIM endpoints defined in Admin Console (enabled ScimStorageProviderFactory)
+        session.getContext().getRealm().getComponentsStream()
+                .filter(m -> ScimEndpointConfigurationStorageProviderFactory.ID.equals(m.getProviderId())
+                             && m.get("enabled", true))
+                .forEach(scimEndpointConfigurationRaw -> {
+                    ScrimProviderConfiguration scrimProviderConfiguration = new ScrimProviderConfiguration(scimEndpointConfigurationRaw);
+                    try {
+                        // Step 3 : create scim clients for each endpoint
+                        if (scimEndpointConfigurationRaw.get(ScrimProviderConfiguration.CONF_KEY_PROPAGATION_GROUP, false)) {
+                            GroupScimService groupScimService = new GroupScimService(session, scrimProviderConfiguration);
+                            groupScimServices.add(groupScimService);
                         }
-                    });
-        } catch (Exception e) {
-            logger.error("[SCIM] Error while refreshing scim clients ", e);
-            // TODO : how to handle exception here ?
-        }
+                        if (scimEndpointConfigurationRaw.get(ScrimProviderConfiguration.CONF_KEY_PROPAGATION_USER, false)) {
+                            UserScimService userScimService = new UserScimService(session, scrimProviderConfiguration);
+                            userScimServices.add(userScimService);
+                        }
+                    } catch (Exception e) {
+                        exceptionHandler.handleInvalidEndpointConfiguration(scimEndpointConfigurationRaw, e);
+                    }
+                });
     }
 
     public void dispatchUserModificationToAll(SCIMPropagationConsumer<UserScimService> operationToDispatch) {
@@ -84,7 +74,7 @@ public class ScimDispatcher {
             }
         });
         // TODO we could iterate on servicesCorrectlyPropagated to undo modification
-        logger.infof("[SCIM] User operation dispatched to %d SCIM server", servicesCorrectlyPropagated.size());
+        LOGGER.infof("[SCIM] User operation dispatched to %d SCIM server", servicesCorrectlyPropagated.size());
     }
 
     public void dispatchGroupModificationToAll(SCIMPropagationConsumer<GroupScimService> operationToDispatch) {
@@ -99,7 +89,7 @@ public class ScimDispatcher {
             }
         });
         // TODO we could iterate on servicesCorrectlyPropagated to undo modification
-        logger.infof("[SCIM] Group operation dispatched to %d SCIM server", servicesCorrectlyPropagated.size());
+        LOGGER.infof("[SCIM] Group operation dispatched to %d SCIM server", servicesCorrectlyPropagated.size());
     }
 
     public void dispatchUserModificationToOne(ComponentModel scimServerConfiguration, SCIMPropagationConsumer<UserScimService> operationToDispatch) {
@@ -109,12 +99,12 @@ public class ScimDispatcher {
         if (matchingClient.isPresent()) {
             try {
                 operationToDispatch.acceptThrows(matchingClient.get());
-                logger.infof("[SCIM] User operation dispatched to SCIM server %s", matchingClient.get().getConfiguration().getId());
+                LOGGER.infof("[SCIM] User operation dispatched to SCIM server %s", matchingClient.get().getConfiguration().getId());
             } catch (ScimPropagationException e) {
                 exceptionHandler.handleException(matchingClient.get().getConfiguration(), e);
             }
         } else {
-            logger.error("[SCIM] Could not find a Scim Client matching User endpoint configuration" + scimServerConfiguration.getId());
+            LOGGER.error("[SCIM] Could not find a Scim Client matching User endpoint configuration" + scimServerConfiguration.getId());
         }
     }
 
@@ -126,12 +116,12 @@ public class ScimDispatcher {
         if (matchingClient.isPresent()) {
             try {
                 operationToDispatch.acceptThrows(matchingClient.get());
-                logger.infof("[SCIM] Group operation dispatched to SCIM server %s", matchingClient.get().getConfiguration().getId());
+                LOGGER.infof("[SCIM] Group operation dispatched to SCIM server %s", matchingClient.get().getConfiguration().getId());
             } catch (ScimPropagationException e) {
                 exceptionHandler.handleException(matchingClient.get().getConfiguration(), e);
             }
         } else {
-            logger.error("[SCIM] Could not find a Scim Client matching Group endpoint configuration" + scimServerConfiguration.getId());
+            LOGGER.error("[SCIM] Could not find a Scim Client matching Group endpoint configuration" + scimServerConfiguration.getId());
         }
     }
 
diff --git a/src/main/java/sh/libre/scim/core/ScimExceptionHandler.java b/src/main/java/sh/libre/scim/core/ScimExceptionHandler.java
index 44d65ff0e114f87af23cf2068d95224fd70d24f9..47b8c718dad5aac127aaef6ea5f6b3346d50feef 100644
--- a/src/main/java/sh/libre/scim/core/ScimExceptionHandler.java
+++ b/src/main/java/sh/libre/scim/core/ScimExceptionHandler.java
@@ -1,6 +1,7 @@
 package sh.libre.scim.core;
 
 import org.jboss.logging.Logger;
+import org.keycloak.component.ComponentModel;
 import org.keycloak.models.KeycloakSession;
 
 /**
@@ -10,8 +11,8 @@ import org.keycloak.models.KeycloakSession;
  * - The thrown exception itself
  */
 public class ScimExceptionHandler {
+    private static final Logger LOGGER = Logger.getLogger(ScimExceptionHandler.class);
 
-    private static final Logger logger = Logger.getLogger(ScimDispatcher.class);
     private final KeycloakSession session;
 
     public ScimExceptionHandler(KeycloakSession session) {
@@ -25,7 +26,14 @@ public class ScimExceptionHandler {
      * @param e                         the occuring exception
      */
     public void handleException(ScrimProviderConfiguration scimProviderConfiguration, ScimPropagationException e) {
-        logger.error("[SCIM] Error while propagating to SCIM endpoint " + scimProviderConfiguration.getId(), e);
-        // TODO session.getTransactionManager().rollback();
+        LOGGER.error("[SCIM] Error while propagating to SCIM endpoint %s", scimProviderConfiguration.getId(), e);
+        // TODO Exception Handling : rollback only for critical operations, if configuration says so
+        // session.getTransactionManager().rollback();
+    }
+
+    public void handleInvalidEndpointConfiguration(ComponentModel scimEndpointConfigurationRaw, Exception e) {
+        LOGGER.error("[SCIM] Invalid Endpoint configuration " + scimEndpointConfigurationRaw.getId(), e);
+        // TODO Exception Handling is it ok to ignore an invalid Scim endpoint Configuration ?
+        // IF not, we should propagate the exception here
     }
 }
diff --git a/src/main/java/sh/libre/scim/core/UserScimService.java b/src/main/java/sh/libre/scim/core/UserScimService.java
index 3c30023c6406e8664ccf9a7931d183a0616e80bc..fbae36236b4fee916133a273e8b1d35ea2dbbc13 100644
--- a/src/main/java/sh/libre/scim/core/UserScimService.java
+++ b/src/main/java/sh/libre/scim/core/UserScimService.java
@@ -20,7 +20,7 @@ import java.util.Optional;
 import java.util.stream.Stream;
 
 public class UserScimService extends AbstractScimService<UserModel, User> {
-    private final Logger logger = Logger.getLogger(UserScimService.class);
+    private final Logger LOGGER = Logger.getLogger(UserScimService.class);
 
     public UserScimService(
             KeycloakSession keycloakSession,
@@ -41,17 +41,18 @@ public class UserScimService extends AbstractScimService<UserModel, User> {
     @Override
     protected Optional<KeycloakId> tryToMap(User resource) {
         Optional<KeycloakId> matchedByUsername = resource.getUserName()
-                        .map(getKeycloakDao()::getUserByUsername)
-                        .map(this::getId);
+                .map(getKeycloakDao()::getUserByUsername)
+                .map(this::getId);
         Optional<KeycloakId> matchedByEmail = resource.getEmails().stream()
                 .findFirst()
                 .flatMap(MultiComplexNode::getValue)
                 .map(getKeycloakDao()::getUserByEmail)
                 .map(this::getId);
         if (matchedByUsername.isPresent()
-                && matchedByEmail.isPresent()
-                && !matchedByUsername.equals(matchedByEmail)) {
-            logger.warnf("found 2 possible users for remote user %s %s", matchedByUsername.get(), matchedByEmail.get());
+            && matchedByEmail.isPresent()
+            && !matchedByUsername.equals(matchedByEmail)) {
+            // TODO Exception Handling : what should we do here ?
+            LOGGER.warnf("found 2 possible users for remote user %s %s", matchedByUsername.get(), matchedByEmail.get());
             return Optional.empty();
         }
         if (matchedByUsername.isPresent()) {
diff --git a/src/main/java/sh/libre/scim/event/ScimEventListenerProvider.java b/src/main/java/sh/libre/scim/event/ScimEventListenerProvider.java
index 4195e6b6188e36c3fb0b9c12b63259a478964cf1..546522294073ec6a0729511a6848931875cea595 100644
--- a/src/main/java/sh/libre/scim/event/ScimEventListenerProvider.java
+++ b/src/main/java/sh/libre/scim/event/ScimEventListenerProvider.java
@@ -228,11 +228,7 @@ public class ScimEventListenerProvider implements EventListenerProvider {
 
     @Override
     public void close() {
-        try {
-            dispatcher.close();
-        } catch (Exception e) {
-            LOGGER.error("Error while closing dispatcher", e);
-        }
+        dispatcher.close();
     }
 
 
diff --git a/src/main/java/sh/libre/scim/storage/ScimEndpointConfigurationStorageProviderFactory.java b/src/main/java/sh/libre/scim/storage/ScimEndpointConfigurationStorageProviderFactory.java
index 00a527fe3ecb22e62e2ebd469dd72061b8fdfd8b..724fa925b72b3082b78d2324d22a4115f42567e8 100644
--- a/src/main/java/sh/libre/scim/storage/ScimEndpointConfigurationStorageProviderFactory.java
+++ b/src/main/java/sh/libre/scim/storage/ScimEndpointConfigurationStorageProviderFactory.java
@@ -31,7 +31,7 @@ import java.util.List;
 public class ScimEndpointConfigurationStorageProviderFactory
         implements UserStorageProviderFactory<ScimEndpointConfigurationStorageProviderFactory.ScimEndpointConfigurationStorageProvider>, ImportSynchronization {
     public static final String ID = "scim";
-    private final Logger logger = Logger.getLogger(ScimEndpointConfigurationStorageProviderFactory.class);
+    private final Logger LOGGER = Logger.getLogger(ScimEndpointConfigurationStorageProviderFactory.class);
 
     @Override
     public String getId() {
@@ -43,7 +43,7 @@ public class ScimEndpointConfigurationStorageProviderFactory
     public SynchronizationResult sync(KeycloakSessionFactory sessionFactory, String realmId,
                                       UserStorageProviderModel model) {
         // TODO if this should be kept here, better document purpose & usage
-        logger.infof("[SCIM] Sync from ScimStorageProvider - Realm %s - Model %s", realmId, model.getId());
+        LOGGER.infof("[SCIM] Sync from ScimStorageProvider - Realm %s - Model %s", realmId, model.getId());
         SynchronizationResult result = new SynchronizationResult();
         KeycloakModelUtils.runJobInTransaction(sessionFactory, session -> {
             RealmModel realm = session.realms().getRealm(realmId);
@@ -78,7 +78,7 @@ public class ScimEndpointConfigurationStorageProviderFactory
                         ScimDispatcher dispatcher = new ScimDispatcher(session);
                         for (GroupModel group : session.groups().getGroupsStream(realm)
                                 .filter(x -> BooleanUtils.TRUE.equals(x.getFirstAttribute("scim-dirty"))).toList()) {
-                            logger.infof("[SCIM] Dirty group: %s", group.getName());
+                            LOGGER.infof("[SCIM] Dirty group: %s", group.getName());
                             dispatcher.dispatchGroupModificationToAll(client -> client.replace(group));
                             group.removeAttribute("scim-dirty");
                         }