You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@unomi.apache.org by sh...@apache.org on 2021/02/08 17:17:21 UTC

[unomi] 15/15: Return error to the client when exception is thrown from Elasticsearch impl (#202)

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

shuber pushed a commit to branch unomi-1.5.x
in repository https://gitbox.apache.org/repos/asf/unomi.git

commit db211807c305c1113a5329f3c606f1c160ff21f8
Author: liatiusim <62...@users.noreply.github.com>
AuthorDate: Thu Nov 19 09:20:29 2020 +0100

    Return error to the client when exception is thrown from Elasticsearch impl (#202)
    
    * Throw exception from elasticsearch impl and add option to return error to the client in this case
    
    * read throwExcetions member from the elasticImpl class - classNotFpund exception
    
    * merge glitch fix
    
    (cherry picked from commit 9e346c97f839a8ed055d68c5b2e842d6852063a1)
---
 .../org/apache/unomi/itests/ProfileServiceIT.java  |   1 +
 .../main/resources/etc/custom.system.properties    |   2 +
 .../ElasticSearchPersistenceServiceImpl.java       |   4 +
 .../apache/unomi/rest/RuntimeExceptionMapper.java  |  38 ++
 .../java/org/apache/unomi/web/ClientServlet.java   |  38 +-
 .../java/org/apache/unomi/web/ContextServlet.java  | 389 +++++++++++----------
 .../apache/unomi/web/EventsCollectorServlet.java   |  24 +-
 7 files changed, 283 insertions(+), 213 deletions(-)

diff --git a/itests/src/test/java/org/apache/unomi/itests/ProfileServiceIT.java b/itests/src/test/java/org/apache/unomi/itests/ProfileServiceIT.java
index d75f608..3d9536b 100644
--- a/itests/src/test/java/org/apache/unomi/itests/ProfileServiceIT.java
+++ b/itests/src/test/java/org/apache/unomi/itests/ProfileServiceIT.java
@@ -22,6 +22,7 @@ import org.apache.unomi.api.services.ProfileService;
 import org.apache.unomi.persistence.spi.PersistenceService;
 import org.apache.unomi.api.services.DefinitionsService;
 import org.apache.unomi.api.PartialList;
+import org.apache.unomi.persistence.elasticsearch.*;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.fail;
diff --git a/package/src/main/resources/etc/custom.system.properties b/package/src/main/resources/etc/custom.system.properties
index 4618ac0..a7b90f3 100644
--- a/package/src/main/resources/etc/custom.system.properties
+++ b/package/src/main/resources/etc/custom.system.properties
@@ -126,6 +126,8 @@ org.apache.unomi.elasticsearch.bulkProcessor.bulkActions=${env:UNOMI_ELASTICSEAR
 org.apache.unomi.elasticsearch.bulkProcessor.bulkSize=${env:UNOMI_ELASTICSEARCH_BULK_SIZE:-5MB}
 org.apache.unomi.elasticsearch.bulkProcessor.flushInterval=${env:UNOMI_ELASTICSEARCH_BULK_FLUSHINTERVAL:-5s}
 org.apache.unomi.elasticsearch.bulkProcessor.backoffPolicy=${env:UNOMI_ELASTICSEARCH_BULK_BACKOFFPOLICY:-exponential}
+# Errors
+org.apache.unomi.elasticsearch.throwExceptions=${env:UNOMI_ELASTICSEARCH_THROW_EXCEPTIONS:-false}
 # Authentication
 org.apache.unomi.elasticsearch.username=${env:UNOMI_ELASTICSEARCH_USERNAME:-}
 org.apache.unomi.elasticsearch.password=${env:UNOMI_ELASTICSEARCH_PASSWORD:-}
diff --git a/persistence-elasticsearch/core/src/main/java/org/apache/unomi/persistence/elasticsearch/ElasticSearchPersistenceServiceImpl.java b/persistence-elasticsearch/core/src/main/java/org/apache/unomi/persistence/elasticsearch/ElasticSearchPersistenceServiceImpl.java
index 5c4a251..8ae4701 100644
--- a/persistence-elasticsearch/core/src/main/java/org/apache/unomi/persistence/elasticsearch/ElasticSearchPersistenceServiceImpl.java
+++ b/persistence-elasticsearch/core/src/main/java/org/apache/unomi/persistence/elasticsearch/ElasticSearchPersistenceServiceImpl.java
@@ -145,6 +145,7 @@ public class ElasticSearchPersistenceServiceImpl implements PersistenceService,
     public static final String PRIMARY_TERM = "primary_term";
 
     private static final Logger logger = LoggerFactory.getLogger(ElasticSearchPersistenceServiceImpl.class.getName());
+    private static boolean throwExceptions = false;
     private RestHighLevelClient client;
     private BulkProcessor bulkProcessor;
     private String elasticSearchAddresses;
@@ -2139,6 +2140,9 @@ public class ElasticSearchPersistenceServiceImpl implements PersistenceService,
             if (logError) {
                 logger.error("Error while executing in class loader", t);
             }
+            if (throwExceptions) {
+                throw new RuntimeException(t);
+            }
         }
 
         private void handleFatalStateError() {
diff --git a/rest/src/main/java/org/apache/unomi/rest/RuntimeExceptionMapper.java b/rest/src/main/java/org/apache/unomi/rest/RuntimeExceptionMapper.java
new file mode 100644
index 0000000..00e1732
--- /dev/null
+++ b/rest/src/main/java/org/apache/unomi/rest/RuntimeExceptionMapper.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.unomi.rest;
+
+import org.osgi.service.component.annotations.Component;
+
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+
+import java.util.HashMap;
+
+@Provider
+@Component(service=ExceptionMapper.class)
+public class RuntimeExceptionMapper implements ExceptionMapper<RuntimeException> {
+
+    @Override
+    public Response toResponse(RuntimeException exception) {
+        HashMap<String, Object> body = new HashMap<>();
+        body.put("errorMessage", "internalServerError");
+        return Response.status(Response.Status.INTERNAL_SERVER_ERROR).header("Content-Type", MediaType.APPLICATION_JSON).entity(body).build();
+    }
+}
\ No newline at end of file
diff --git a/wab/src/main/java/org/apache/unomi/web/ClientServlet.java b/wab/src/main/java/org/apache/unomi/web/ClientServlet.java
index f385a53..59de0ce 100644
--- a/wab/src/main/java/org/apache/unomi/web/ClientServlet.java
+++ b/wab/src/main/java/org/apache/unomi/web/ClientServlet.java
@@ -67,26 +67,30 @@ public class ClientServlet extends HttpServlet {
 
     @Override
     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
-        String[] pathInfo = req.getPathInfo().substring(1).split("\\.");
-        if (pathInfo != null && pathInfo.length > 0) {
-            String operation = pathInfo[0];
-            String param = pathInfo[1];
-            switch (operation) {
-                case "myprofile":
-                    if (allowedProfileDownloadFormats.contains(param)) {
-                        donwloadCurrentProfile(req, resp, param);
-                    } else {
-                        resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
-                    }
-                    break;
-                default:
-                    resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
+        try {
+            String[] pathInfo = req.getPathInfo().substring(1).split("\\.");
+            if (pathInfo != null && pathInfo.length > 0) {
+                String operation = pathInfo[0];
+                String param = pathInfo[1];
+                switch (operation) {
+                    case "myprofile":
+                        if (allowedProfileDownloadFormats.contains(param)) {
+                            donwloadCurrentProfile(req, resp, param);
+                        } else {
+                            resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+                        }
+                        break;
+                    default:
+                        resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
 
+                }
+            } else {
+                resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
             }
-        } else {
-            resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
+        } catch (Throwable t) { // Here in order to return generic message instead of the whole stack trace in case of not caught exception
+            logger.error("ClientServlet failed to execute get", t);
+            resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Internal server error");
         }
-
     }
 
     @Override
diff --git a/wab/src/main/java/org/apache/unomi/web/ContextServlet.java b/wab/src/main/java/org/apache/unomi/web/ContextServlet.java
index 033ef5c..f45a891 100644
--- a/wab/src/main/java/org/apache/unomi/web/ContextServlet.java
+++ b/wab/src/main/java/org/apache/unomi/web/ContextServlet.java
@@ -72,234 +72,239 @@ public class ContextServlet extends HttpServlet {
 
     @Override
     public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
-        final Date timestamp = new Date();
-        if (request.getParameter("timestamp") != null) {
-            timestamp.setTime(Long.parseLong(request.getParameter("timestamp")));
-        }
+        try {
+            final Date timestamp = new Date();
+            if (request.getParameter("timestamp") != null) {
+                timestamp.setTime(Long.parseLong(request.getParameter("timestamp")));
+            }
 
-        // set up CORS headers as soon as possible so that errors are not misconstrued on the client for CORS errors
-        HttpUtils.setupCORSHeaders(request, response);
+            // set up CORS headers as soon as possible so that errors are not misconstrued on the client for CORS errors
+            HttpUtils.setupCORSHeaders(request, response);
 
-        // Handle OPTIONS request
-        String httpMethod = request.getMethod();
-        if ("options".equals(httpMethod.toLowerCase())) {
-            response.flushBuffer();
-            if (logger.isDebugEnabled()) {
-                logger.debug("OPTIONS request received. No context will be returned.");
+            // Handle OPTIONS request
+            String httpMethod = request.getMethod();
+            if ("options".equals(httpMethod.toLowerCase())) {
+                response.flushBuffer();
+                if (logger.isDebugEnabled()) {
+                    logger.debug("OPTIONS request received. No context will be returned.");
+                }
+                return;
             }
-            return;
-        }
 
-        // Handle persona
-        Profile profile = null;
-        Session session = null;
-        String personaId = request.getParameter("personaId");
-        if (personaId != null) {
-            PersonaWithSessions personaWithSessions = profileService.loadPersonaWithSessions(personaId);
-            if (personaWithSessions == null) {
-                logger.error("Couldn't find persona with id=" + personaId);
-                profile = null;
-            } else {
-                profile = personaWithSessions.getPersona();
-                session = personaWithSessions.getLastSession();
+            // Handle persona
+            Profile profile = null;
+            Session session = null;
+            String personaId = request.getParameter("personaId");
+            if (personaId != null) {
+                PersonaWithSessions personaWithSessions = profileService.loadPersonaWithSessions(personaId);
+                if (personaWithSessions == null) {
+                    logger.error("Couldn't find persona with id=" + personaId);
+                    profile = null;
+                } else {
+                    profile = personaWithSessions.getPersona();
+                    session = personaWithSessions.getLastSession();
+                }
             }
-        }
 
-        // Extract payload
-        ContextRequest contextRequest = null;
-        String scope = null;
-        String sessionId = null;
-        String profileId = null;
-        String stringPayload = HttpUtils.getPayload(request);
-        if (stringPayload != null) {
-            ObjectMapper mapper = CustomObjectMapper.getObjectMapper();
-            JsonFactory factory = mapper.getFactory();
-            try {
-                contextRequest = mapper.readValue(factory.createParser(stringPayload), ContextRequest.class);
-            } catch (Exception e) {
-                ((HttpServletResponse)response).sendError(HttpServletResponse.SC_BAD_REQUEST, "Check logs for more details");
-                logger.error("Cannot read payload " + stringPayload, e);
-                return;
-            }
-            if (contextRequest.getSource() != null) {
-                scope = contextRequest.getSource().getScope();
+            // Extract payload
+            ContextRequest contextRequest = null;
+            String scope = null;
+            String sessionId = null;
+            String profileId = null;
+            String stringPayload = HttpUtils.getPayload(request);
+            if (stringPayload != null) {
+                ObjectMapper mapper = CustomObjectMapper.getObjectMapper();
+                JsonFactory factory = mapper.getFactory();
+                try {
+                    contextRequest = mapper.readValue(factory.createParser(stringPayload), ContextRequest.class);
+                } catch (Exception e) {
+                    ((HttpServletResponse)response).sendError(HttpServletResponse.SC_BAD_REQUEST, "Check logs for more details");
+                    logger.error("Cannot read payload " + stringPayload, e);
+                    return;
+                }
+                if (contextRequest.getSource() != null) {
+                    scope = contextRequest.getSource().getScope();
+                }
+                sessionId = contextRequest.getSessionId();
+                profileId = contextRequest.getProfileId();
             }
-            sessionId = contextRequest.getSessionId();
-            profileId = contextRequest.getProfileId();
-        }
 
-        if (sessionId == null) {
-            sessionId = request.getParameter("sessionId");
-        }
+            if (sessionId == null) {
+                sessionId = request.getParameter("sessionId");
+            }
 
-        if (profileId == null) {
-            // Get profile id from the cookie
-            profileId = ServletCommon.getProfileIdCookieValue(request, profileIdCookieName);
-        }
+            if (profileId == null) {
+                // Get profile id from the cookie
+                profileId = ServletCommon.getProfileIdCookieValue(request, profileIdCookieName);
+            }
 
-        if (profileId == null && sessionId == null && personaId == null) {
-            ((HttpServletResponse)response).sendError(HttpServletResponse.SC_BAD_REQUEST, "Check logs for more details");
-            logger.error("Couldn't find profileId, sessionId or personaId in incoming request! Stopped processing request. See debug level for more information");
-            if (logger.isDebugEnabled()) {
-                logger.debug("Request dump: {}", HttpUtils.dumpRequestInfo(request));
+            if (profileId == null && sessionId == null && personaId == null) {
+                ((HttpServletResponse)response).sendError(HttpServletResponse.SC_BAD_REQUEST, "Check logs for more details");
+                logger.error("Couldn't find profileId, sessionId or personaId in incoming request! Stopped processing request. See debug level for more information");
+                if (logger.isDebugEnabled()) {
+                    logger.debug("Request dump: {}", HttpUtils.dumpRequestInfo(request));
+                }
+                return;
             }
-            return;
-        }
 
-        int changes = EventService.NO_CHANGE;
-        if (profile == null) {
-            // Not a persona, resolve profile now
-            boolean profileCreated = false;
-
-            boolean invalidateProfile = request.getParameter("invalidateProfile") != null ?
-                    new Boolean(request.getParameter("invalidateProfile")) : false;
-            if (profileId == null || invalidateProfile) {
-                // no profileId cookie was found or the profile has to be invalidated, we generate a new one and create the profile in the profile service
-                profile = createNewProfile(null, response, timestamp);
-                profileCreated = true;
-            } else {
-                profile = profileService.load(profileId);
-                if (profile == null) {
-                    // this can happen if we have an old cookie but have reset the server,
-                    // or if we merged the profiles and somehow this cookie didn't get updated.
-                    profile = createNewProfile(profileId, response, timestamp);
+            int changes = EventService.NO_CHANGE;
+            if (profile == null) {
+                // Not a persona, resolve profile now
+                boolean profileCreated = false;
+
+                boolean invalidateProfile = request.getParameter("invalidateProfile") != null ?
+                        new Boolean(request.getParameter("invalidateProfile")) : false;
+                if (profileId == null || invalidateProfile) {
+                    // no profileId cookie was found or the profile has to be invalidated, we generate a new one and create the profile in the profile service
+                    profile = createNewProfile(null, response, timestamp);
                     profileCreated = true;
                 } else {
-                    Changes changesObject = checkMergedProfile(response, profile, session);
-                    changes |= changesObject.getChangeType();
-                    profile = changesObject.getProfile();
+                    profile = profileService.load(profileId);
+                    if (profile == null) {
+                        // this can happen if we have an old cookie but have reset the server,
+                        // or if we merged the profiles and somehow this cookie didn't get updated.
+                        profile = createNewProfile(profileId, response, timestamp);
+                        profileCreated = true;
+                    } else {
+                        Changes changesObject = checkMergedProfile(response, profile, session);
+                        changes |= changesObject.getChangeType();
+                        profile = changesObject.getProfile();
+                    }
                 }
-            }
 
-            Profile sessionProfile;
-            boolean invalidateSession = request.getParameter("invalidateSession") != null ?
-                    new Boolean(request.getParameter("invalidateSession")) : false;
-            if (StringUtils.isNotBlank(sessionId) && !invalidateSession) {
-                session = profileService.loadSession(sessionId, timestamp);
-                if (session != null) {
-                    sessionProfile = session.getProfile();
-
-                    boolean anonymousSessionProfile = sessionProfile.isAnonymousProfile();
-                    if (!profile.isAnonymousProfile() && !anonymousSessionProfile && !profile.getItemId().equals(sessionProfile.getItemId())) {
-                        // Session user has been switched, profile id in cookie is not up to date
-                        // We must reload the profile with the session ID as some properties could be missing from the session profile
-                        // #personalIdentifier
-                        profile = profileService.load(sessionProfile.getItemId());
-                        if (profile != null) {
-                            HttpUtils.sendProfileCookie(profile, response, profileIdCookieName, profileIdCookieDomain, profileIdCookieMaxAgeInSeconds);
-                        } else {
-                            logger.warn("Couldn't load profile {} referenced in session {}", sessionProfile.getItemId(), session.getItemId());
+                Profile sessionProfile;
+                boolean invalidateSession = request.getParameter("invalidateSession") != null ?
+                        new Boolean(request.getParameter("invalidateSession")) : false;
+                if (StringUtils.isNotBlank(sessionId) && !invalidateSession) {
+                    session = profileService.loadSession(sessionId, timestamp);
+                    if (session != null) {
+                        sessionProfile = session.getProfile();
+
+                        boolean anonymousSessionProfile = sessionProfile.isAnonymousProfile();
+                        if (!profile.isAnonymousProfile() && !anonymousSessionProfile && !profile.getItemId().equals(sessionProfile.getItemId())) {
+                            // Session user has been switched, profile id in cookie is not up to date
+                            // We must reload the profile with the session ID as some properties could be missing from the session profile
+                            // #personalIdentifier
+                            profile = profileService.load(sessionProfile.getItemId());
+                            if (profile != null) {
+                                HttpUtils.sendProfileCookie(profile, response, profileIdCookieName, profileIdCookieDomain, profileIdCookieMaxAgeInSeconds);
+                            } else {
+                                logger.warn("Couldn't load profile {} referenced in session {}", sessionProfile.getItemId(), session.getItemId());
+                            }
                         }
-                    }
 
-                    // Handle anonymous situation
-                    Boolean requireAnonymousBrowsing = privacyService.isRequireAnonymousBrowsing(profile);
-                    if (requireAnonymousBrowsing && anonymousSessionProfile) {
-                        // User wants to browse anonymously, anonymous profile is already set.
-                    } else if (requireAnonymousBrowsing && !anonymousSessionProfile) {
-                        // User wants to browse anonymously, update the sessionProfile to anonymous profile
-                        sessionProfile = privacyService.getAnonymousProfile(profile);
-                        session.setProfile(sessionProfile);
-                        changes |= EventService.SESSION_UPDATED;
-                    } else if (!requireAnonymousBrowsing && anonymousSessionProfile) {
-                        // User does not want to browse anonymously anymore, update the sessionProfile to real profile
-                        sessionProfile = profile;
-                        session.setProfile(sessionProfile);
-                        changes |= EventService.SESSION_UPDATED;
-                    } else if (!requireAnonymousBrowsing && !anonymousSessionProfile) {
-                        // User does not want to browse anonymously, use the real profile. Check that session contains the current profile.
-                        sessionProfile = profile;
-                        if (!session.getProfileId().equals(sessionProfile.getItemId())) {
+                        // Handle anonymous situation
+                        Boolean requireAnonymousBrowsing = privacyService.isRequireAnonymousBrowsing(profile);
+                        if (requireAnonymousBrowsing && anonymousSessionProfile) {
+                            // User wants to browse anonymously, anonymous profile is already set.
+                        } else if (requireAnonymousBrowsing && !anonymousSessionProfile) {
+                            // User wants to browse anonymously, update the sessionProfile to anonymous profile
+                            sessionProfile = privacyService.getAnonymousProfile(profile);
+                            session.setProfile(sessionProfile);
+                            changes |= EventService.SESSION_UPDATED;
+                        } else if (!requireAnonymousBrowsing && anonymousSessionProfile) {
+                            // User does not want to browse anonymously anymore, update the sessionProfile to real profile
+                            sessionProfile = profile;
+                            session.setProfile(sessionProfile);
                             changes |= EventService.SESSION_UPDATED;
+                        } else if (!requireAnonymousBrowsing && !anonymousSessionProfile) {
+                            // User does not want to browse anonymously, use the real profile. Check that session contains the current profile.
+                            sessionProfile = profile;
+                            if (!session.getProfileId().equals(sessionProfile.getItemId())) {
+                                changes |= EventService.SESSION_UPDATED;
+                            }
+                            session.setProfile(sessionProfile);
                         }
-                        session.setProfile(sessionProfile);
                     }
                 }
-            }
 
-            if (session == null || invalidateSession) {
-                sessionProfile = privacyService.isRequireAnonymousBrowsing(profile) ? privacyService.getAnonymousProfile(profile) : profile;
-
-                if (StringUtils.isNotBlank(sessionId)) {
-                    // Only save session and send event if a session id was provided, otherwise keep transient session
-                    session = new Session(sessionId, sessionProfile, timestamp, scope);
-                    changes |= EventService.SESSION_UPDATED;
-                    Event event = new Event("sessionCreated", session, profile, scope, null, session, timestamp);
-                    if (sessionProfile.isAnonymousProfile()) {
-                        // Do not keep track of profile in event
-                        event.setProfileId(null);
-                    }
-                    event.getAttributes().put(Event.HTTP_REQUEST_ATTRIBUTE, request);
-                    event.getAttributes().put(Event.HTTP_RESPONSE_ATTRIBUTE, response);
-                    if (logger.isDebugEnabled()) {
-                        logger.debug("Received event {} for profile={} session={} target={} timestamp={}",
-                                event.getEventType(), profile.getItemId(), session.getItemId(), event.getTarget(), timestamp);
+                if (session == null || invalidateSession) {
+                    sessionProfile = privacyService.isRequireAnonymousBrowsing(profile) ? privacyService.getAnonymousProfile(profile) : profile;
+
+                    if (StringUtils.isNotBlank(sessionId)) {
+                        // Only save session and send event if a session id was provided, otherwise keep transient session
+                        session = new Session(sessionId, sessionProfile, timestamp, scope);
+                        changes |= EventService.SESSION_UPDATED;
+                        Event event = new Event("sessionCreated", session, profile, scope, null, session, timestamp);
+                        if (sessionProfile.isAnonymousProfile()) {
+                            // Do not keep track of profile in event
+                            event.setProfileId(null);
+                        }
+                        event.getAttributes().put(Event.HTTP_REQUEST_ATTRIBUTE, request);
+                        event.getAttributes().put(Event.HTTP_RESPONSE_ATTRIBUTE, response);
+                        if (logger.isDebugEnabled()) {
+                            logger.debug("Received event {} for profile={} session={} target={} timestamp={}",
+                                    event.getEventType(), profile.getItemId(), session.getItemId(), event.getTarget(), timestamp);
+                        }
+                        changes |= eventService.send(event);
                     }
-                    changes |= eventService.send(event);
                 }
-            }
 
-            if (profileCreated) {
-                changes |= EventService.PROFILE_UPDATED;
+                if (profileCreated) {
+                    changes |= EventService.PROFILE_UPDATED;
 
-                Event profileUpdated = new Event("profileUpdated", session, profile, scope, null, profile, timestamp);
-                profileUpdated.setPersistent(false);
-                profileUpdated.getAttributes().put(Event.HTTP_REQUEST_ATTRIBUTE, request);
-                profileUpdated.getAttributes().put(Event.HTTP_RESPONSE_ATTRIBUTE, response);
+                    Event profileUpdated = new Event("profileUpdated", session, profile, scope, null, profile, timestamp);
+                    profileUpdated.setPersistent(false);
+                    profileUpdated.getAttributes().put(Event.HTTP_REQUEST_ATTRIBUTE, request);
+                    profileUpdated.getAttributes().put(Event.HTTP_RESPONSE_ATTRIBUTE, response);
 
-                if (logger.isDebugEnabled()) {
-                    logger.debug("Received event {} for profile={} {} target={} timestamp={}", profileUpdated.getEventType(), profile.getItemId(),
-                            " session=" + (session != null ? session.getItemId() : null), profileUpdated.getTarget(), timestamp);
+                    if (logger.isDebugEnabled()) {
+                        logger.debug("Received event {} for profile={} {} target={} timestamp={}", profileUpdated.getEventType(), profile.getItemId(),
+                                " session=" + (session != null ? session.getItemId() : null), profileUpdated.getTarget(), timestamp);
+                    }
+                    changes |= eventService.send(profileUpdated);
                 }
-                changes |= eventService.send(profileUpdated);
             }
-        }
 
-        ContextResponse contextResponse = new ContextResponse();
-        contextResponse.setProfileId(profile.getItemId());
-        if (session != null) {
-            contextResponse.setSessionId(session.getItemId());
-        } else if (sessionId != null) {
-            contextResponse.setSessionId(sessionId);
-        }
+            ContextResponse contextResponse = new ContextResponse();
+            contextResponse.setProfileId(profile.getItemId());
+            if (session != null) {
+                contextResponse.setSessionId(session.getItemId());
+            } else if (sessionId != null) {
+                contextResponse.setSessionId(sessionId);
+            }
 
-        if (contextRequest != null) {
-            Changes changesObject = handleRequest(contextRequest, session, profile, contextResponse, request, response, timestamp);
-            changes |= changesObject.getChangeType();
-            profile = changesObject.getProfile();
-        }
+            if (contextRequest != null) {
+                Changes changesObject = handleRequest(contextRequest, session, profile, contextResponse, request, response, timestamp);
+                changes |= changesObject.getChangeType();
+                profile = changesObject.getProfile();
+            }
 
-        if ((changes & EventService.PROFILE_UPDATED) == EventService.PROFILE_UPDATED) {
-            profileService.save(profile);
-            contextResponse.setProfileId(profile.getItemId());
-        }
-        if ((changes & EventService.SESSION_UPDATED) == EventService.SESSION_UPDATED && session != null) {
-            profileService.saveSession(session);
-            contextResponse.setSessionId(session.getItemId());
-        }
+            if ((changes & EventService.PROFILE_UPDATED) == EventService.PROFILE_UPDATED) {
+                profileService.save(profile);
+                contextResponse.setProfileId(profile.getItemId());
+            }
+            if ((changes & EventService.SESSION_UPDATED) == EventService.SESSION_UPDATED && session != null) {
+                profileService.saveSession(session);
+                contextResponse.setSessionId(session.getItemId());
+            }
 
-        if ((changes & EventService.ERROR) == EventService.ERROR) {
-            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
-        }
+            if ((changes & EventService.ERROR) == EventService.ERROR) {
+                response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+            }
 
-        String extension = request.getRequestURI().substring(request.getRequestURI().lastIndexOf(".") + 1);
-        boolean noScript = "json".equals(extension);
-        String contextAsJSONString = CustomObjectMapper.getObjectMapper().writeValueAsString(contextResponse);
-        Writer responseWriter;
-        response.setCharacterEncoding("UTF-8");
-        if (noScript) {
-            responseWriter = response.getWriter();
-            response.setContentType("application/json");
-            IOUtils.write(contextAsJSONString, responseWriter);
-        } else {
-            responseWriter = response.getWriter();
-            responseWriter.append("window.digitalData = window.digitalData || {};\n")
-                    .append("var cxs = ")
-                    .append(contextAsJSONString)
-                    .append(";\n");
-        }
+            String extension = request.getRequestURI().substring(request.getRequestURI().lastIndexOf(".") + 1);
+            boolean noScript = "json".equals(extension);
+            String contextAsJSONString = CustomObjectMapper.getObjectMapper().writeValueAsString(contextResponse);
+            Writer responseWriter;
+            response.setCharacterEncoding("UTF-8");
+            if (noScript) {
+                responseWriter = response.getWriter();
+                response.setContentType("application/json");
+                IOUtils.write(contextAsJSONString, responseWriter);
+            } else {
+                responseWriter = response.getWriter();
+                responseWriter.append("window.digitalData = window.digitalData || {};\n")
+                        .append("var cxs = ")
+                        .append(contextAsJSONString)
+                        .append(";\n");
+            }
 
-        responseWriter.flush();
+            responseWriter.flush();
+        } catch (Throwable t) { // Here in order to return generic message instead of the whole stack trace in case of not caught exception
+            logger.error("ContextServlet failed to execute request", t);
+            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Internal server error");
+        }
     }
 
     private Changes checkMergedProfile(ServletResponse response, Profile profile, Session session) {
diff --git a/wab/src/main/java/org/apache/unomi/web/EventsCollectorServlet.java b/wab/src/main/java/org/apache/unomi/web/EventsCollectorServlet.java
index 2c34659..313b25b 100644
--- a/wab/src/main/java/org/apache/unomi/web/EventsCollectorServlet.java
+++ b/wab/src/main/java/org/apache/unomi/web/EventsCollectorServlet.java
@@ -62,19 +62,35 @@ public class EventsCollectorServlet extends HttpServlet {
 
     @Override
     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
-        doEvent(req, resp);
+        try {
+            doEvent(req, resp);
+        } catch (Throwable t) { // Here in order to return generic message instead of the whole stack trace in case of not caught exception
+            logger.error("EventsCollectorServlet failed to execute get", t);
+            resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Internal server error");
+        }
     }
 
     @Override
     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
-        doEvent(req, resp);
+        try {
+            doEvent(req, resp);
+        } catch (Throwable t) { // Here in order to return generic message instead of the whole stack trace in case of not caught exception
+            logger.error("EventsCollectorServlet failed to execute post", t);
+            resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Internal server error");
+        }
     }
 
     @Override
     protected void doOptions(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 //        logger.debug(HttpUtils.dumpRequestInfo(request));
-        HttpUtils.setupCORSHeaders(request, response);
-        response.flushBuffer();
+        try {
+            HttpUtils.setupCORSHeaders(request, response);
+            response.flushBuffer();
+        }
+        catch (Throwable t) { // Here in order to return generic message instead of the whole stack trace in case of not caught exception
+            logger.error("EventsCollectorServlet failed to execute doOptions request", t);
+            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Internal server error");
+        }
     }
 
     private void doEvent(HttpServletRequest request, HttpServletResponse response) throws IOException {