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

enapps-enorman pushed a commit to branch master
in repository 
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-discovery-base.git


The following commit(s) were added to refs/heads/master by this push:
     new ebb4caf  SLING-13228 fix exceptions should not be thrown from servlet 
methods (#23)
ebb4caf is described below

commit ebb4cafafae2be4f397241f6c2d5613b7954ec40
Author: Eric Norman <[email protected]>
AuthorDate: Sat May 30 12:43:00 2026 -0700

    SLING-13228 fix exceptions should not be thrown from servlet methods (#23)
---
 .../connectors/ping/TopologyConnectorServlet.java  | 262 ++++++++++++---------
 1 file changed, 153 insertions(+), 109 deletions(-)

diff --git 
a/src/main/java/org/apache/sling/discovery/base/connectors/ping/TopologyConnectorServlet.java
 
b/src/main/java/org/apache/sling/discovery/base/connectors/ping/TopologyConnectorServlet.java
index d30f0ce..0db302e 100644
--- 
a/src/main/java/org/apache/sling/discovery/base/connectors/ping/TopologyConnectorServlet.java
+++ 
b/src/main/java/org/apache/sling/discovery/base/connectors/ping/TopologyConnectorServlet.java
@@ -177,153 +177,197 @@ public class TopologyConnectorServlet extends 
HttpServlet {
     }
 
     @Override
-    protected void doDelete(HttpServletRequest request, HttpServletResponse 
response)
-            throws ServletException, IOException {
+    protected void doDelete(HttpServletRequest request, HttpServletResponse 
response) {
 
         if (!isWhitelisted(request)) {
             // in theory it would be 403==forbidden, but that would reveal that
             // a resource would exist there in the first place
-            response.sendError(HttpServletResponse.SC_NOT_FOUND);
+            try {
+                response.sendError(HttpServletResponse.SC_NOT_FOUND);
+            } catch (IOException e) {
+                logger.error("doDelete: IOException while sending error 
response: " + e, e);
+            }
             return;
         }
 
-        final String[] pathInfo = request.getPathInfo().split("\\.");
-        final String extension = pathInfo.length == 3 ? pathInfo[2] : "";
-        if (!"json".equals(extension)) {
-            response.sendError(HttpServletResponse.SC_NOT_FOUND);
-            return;
-        }
-        final String selector = pathInfo.length == 3 ? pathInfo[1] : "";
+        try {
+            final String[] pathInfo = request.getPathInfo().split("\\.");
+            final String extension = pathInfo.length == 3 ? pathInfo[2] : "";
+            if (!"json".equals(extension)) {
+                response.sendError(HttpServletResponse.SC_NOT_FOUND);
+                return;
+            }
+            final String selector = pathInfo.length == 3 ? pathInfo[1] : "";
 
-        announcementRegistry.unregisterAnnouncement(selector);
+            announcementRegistry.unregisterAnnouncement(selector);
+        } catch (IOException e) {
+            logger.error("doDelete: IOException occurred: " + e, e);
+            try {
+                
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+            } catch (IOException e2) {
+                logger.error("doDelete: IOException while sending error 
response: " + e2, e2);
+            }
+        } catch (Exception e) {
+            logger.error("doDelete: Unexpected exception occurred: " + e, e);
+            try {
+                
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+            } catch (IOException e2) {
+                logger.error("doDelete: IOException while sending error 
response: " + e2, e2);
+            }
+        }
     }
 
     @Override
-    protected void doPut(HttpServletRequest request, HttpServletResponse 
response)
-            throws ServletException, IOException {
+    protected void doPut(HttpServletRequest request, HttpServletResponse 
response) {
 
         if (!isWhitelisted(request)) {
             // in theory it would be 403==forbidden, but that would reveal that
             // a resource would exist there in the first place
-            response.sendError(HttpServletResponse.SC_NOT_FOUND);
-            return;
-        }
-
-        final String[] pathInfo = request.getPathInfo().split("\\.");
-        final String extension = pathInfo.length == 3 ? pathInfo[2] : "";
-        if (!"json".equals(extension)) {
-            response.sendError(HttpServletResponse.SC_NOT_FOUND);
+            try {
+                response.sendError(HttpServletResponse.SC_NOT_FOUND);
+            } catch (IOException e) {
+                logger.error("doPut: IOException while sending error response: 
" + e, e);
+            }
             return;
         }
 
-        final String selector = pathInfo.length == 3 ? pathInfo[1] : "";
-
-        String topologyAnnouncementJSON = 
requestValidator.decodeMessage(request);
-
-        if (logger.isDebugEnabled()) {
-            // javasecurity:S5145: Replace pattern-breaking characters
-            logger.debug("doPost: incoming topology announcement is: "
-                    + topologyAnnouncementJSON.replaceAll("[\n\r\t]", "_"));
-        }
-        final Announcement incomingTopologyAnnouncement;
         try {
-            incomingTopologyAnnouncement = 
Announcement.fromJSON(topologyAnnouncementJSON);
-
-            if (!incomingTopologyAnnouncement.getOwnerId().equals(selector)) {
-                response.sendError(HttpServletResponse.SC_BAD_REQUEST);
+            final String[] pathInfo = request.getPathInfo().split("\\.");
+            final String extension = pathInfo.length == 3 ? pathInfo[2] : "";
+            if (!"json".equals(extension)) {
+                response.sendError(HttpServletResponse.SC_NOT_FOUND);
                 return;
             }
 
-            String slingId = clusterViewService.getSlingId();
-            if (slingId == null) {
-                
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
-                logger.info("doPut: no slingId available. Service not ready as 
expected at the moment.");
-                return;
-            }
-            incomingTopologyAnnouncement.removeInherited(slingId);
+            final String selector = pathInfo.length == 3 ? pathInfo[1] : "";
 
-            final Announcement replyAnnouncement = new Announcement(slingId);
+            String topologyAnnouncementJSON = 
requestValidator.decodeMessage(request);
 
-            long backoffInterval = -1;
-            ClusterView clusterView = clusterViewService.getLocalClusterView();
-            if (!incomingTopologyAnnouncement.isCorrectVersion()) {
-                logger.warn("doPost: rejecting an announcement from an 
incompatible connector protocol version: "
-                        + incomingTopologyAnnouncement);
-                response.sendError(HttpServletResponse.SC_BAD_REQUEST);
-                return;
-            } else if (ClusterViewHelper.contains(clusterView, 
incomingTopologyAnnouncement.getOwnerId())) {
-                if (logger.isDebugEnabled()) {
-                    logger.debug("doPost: rejecting an announcement from an 
instance that is part of my cluster: "
-                            + incomingTopologyAnnouncement);
-                }
-                // marking as 'loop'
-                replyAnnouncement.setLoop(true);
-                backoffInterval = config.getBackoffStandbyInterval();
-            } else if (ClusterViewHelper.containsAny(clusterView, 
incomingTopologyAnnouncement.listInstances())) {
-                if (logger.isDebugEnabled()) {
-                    logger.debug(
-                            "doPost: rejecting an announcement as it contains 
instance(s) that is/are part of my cluster: "
-                                    + incomingTopologyAnnouncement);
+            if (logger.isDebugEnabled()) {
+                // javasecurity:S5145: Replace pattern-breaking characters
+                logger.debug("doPut: incoming topology announcement is: "
+                        + topologyAnnouncementJSON.replaceAll("[\n\r\t]", 
"_"));
+            }
+            final Announcement incomingTopologyAnnouncement;
+            try {
+                incomingTopologyAnnouncement = 
Announcement.fromJSON(topologyAnnouncementJSON);
+
+                if 
(!incomingTopologyAnnouncement.getOwnerId().equals(selector)) {
+                    response.sendError(HttpServletResponse.SC_BAD_REQUEST);
+                    return;
                 }
-                // marking as 'loop'
-                replyAnnouncement.setLoop(true);
-                backoffInterval = config.getBackoffStandbyInterval();
-            } else {
-                backoffInterval = 
announcementRegistry.registerAnnouncement(incomingTopologyAnnouncement);
-                if (logger.isDebugEnabled()) {
-                    logger.debug("doPost: backoffInterval after registration: 
" + backoffInterval);
+
+                String slingId = clusterViewService.getSlingId();
+                if (slingId == null) {
+                    
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+                    logger.info("doPut: no slingId available. Service not 
ready as expected at the moment.");
+                    return;
                 }
-                if (backoffInterval == -1) {
+                incomingTopologyAnnouncement.removeInherited(slingId);
+
+                final Announcement replyAnnouncement = new 
Announcement(slingId);
+
+                long backoffInterval = -1;
+                ClusterView clusterView = 
clusterViewService.getLocalClusterView();
+                if (!incomingTopologyAnnouncement.isCorrectVersion()) {
+                    logger.warn("doPut: rejecting an announcement from an 
incompatible connector protocol version: "
+                            + incomingTopologyAnnouncement);
+                    response.sendError(HttpServletResponse.SC_BAD_REQUEST);
+                    return;
+                } else if (ClusterViewHelper.contains(clusterView, 
incomingTopologyAnnouncement.getOwnerId())) {
+                    if (logger.isDebugEnabled()) {
+                        logger.debug("doPut: rejecting an announcement from an 
instance that is part of my cluster: "
+                                + incomingTopologyAnnouncement);
+                    }
+                    // marking as 'loop'
+                    replyAnnouncement.setLoop(true);
+                    backoffInterval = config.getBackoffStandbyInterval();
+                } else if (ClusterViewHelper.containsAny(clusterView, 
incomingTopologyAnnouncement.listInstances())) {
                     if (logger.isDebugEnabled()) {
                         logger.debug(
-                                "doPost: rejecting an announcement from an 
instance that I already see in my topology: "
+                                "doPut: rejecting an announcement as it 
contains instance(s) that is/are part of my cluster: "
                                         + incomingTopologyAnnouncement);
                     }
                     // marking as 'loop'
                     replyAnnouncement.setLoop(true);
                     backoffInterval = config.getBackoffStandbyInterval();
                 } else {
-                    // normal, successful case: replying with the part of the 
topology which this instance sees
-                    replyAnnouncement.setLocalCluster(clusterView);
-                    announcementRegistry.addAllExcept(
-                            replyAnnouncement, clusterView, (receivingSlingId, 
announcement) -> {
-                                if 
(announcement.getPrimaryKey().equals(incomingTopologyAnnouncement.getPrimaryKey()))
 {
-                                    return false;
-                                }
-                                return true;
-                            });
+                    backoffInterval = 
announcementRegistry.registerAnnouncement(incomingTopologyAnnouncement);
+                    if (logger.isDebugEnabled()) {
+                        logger.debug("doPut: backoffInterval after 
registration: " + backoffInterval);
+                    }
+                    if (backoffInterval == -1) {
+                        if (logger.isDebugEnabled()) {
+                            logger.debug(
+                                    "doPut: rejecting an announcement from an 
instance that I already see in my topology: "
+                                            + incomingTopologyAnnouncement);
+                        }
+                        // marking as 'loop'
+                        replyAnnouncement.setLoop(true);
+                        backoffInterval = config.getBackoffStandbyInterval();
+                    } else {
+                        // normal, successful case: replying with the part of 
the topology which this instance sees
+                        replyAnnouncement.setLocalCluster(clusterView);
+                        announcementRegistry.addAllExcept(
+                                replyAnnouncement, clusterView, 
(receivingSlingId, announcement) -> {
+                                    if (announcement
+                                            .getPrimaryKey()
+                                            
.equals(incomingTopologyAnnouncement.getPrimaryKey())) {
+                                        return false;
+                                    }
+                                    return true;
+                                });
+                    }
                 }
-            }
-            if (backoffInterval > 0) {
-                replyAnnouncement.setBackoffInterval(backoffInterval);
-                if (logger.isDebugEnabled()) {
-                    logger.debug("doPost: backoffInterval for client set to " 
+ replyAnnouncement.getBackoffInterval());
+                if (backoffInterval > 0) {
+                    replyAnnouncement.setBackoffInterval(backoffInterval);
+                    if (logger.isDebugEnabled()) {
+                        logger.debug(
+                                "doPut: backoffInterval for client set to " + 
replyAnnouncement.getBackoffInterval());
+                    }
                 }
+                final String p = 
requestValidator.encodeMessage(replyAnnouncement.asJSON());
+                requestValidator.trustMessage(response, request, p);
+                // gzip the response if the client accepts this
+                final String acceptEncodingHeader = 
request.getHeader("Accept-Encoding");
+                if (acceptEncodingHeader != null && 
acceptEncodingHeader.contains("gzip")) {
+                    // tell the client that the content is gzipped:
+                    response.setHeader("Content-Encoding", "gzip");
+
+                    // then gzip the body
+                    final GZIPOutputStream gzipOut = new 
GZIPOutputStream(response.getOutputStream());
+                    try {
+                        gzipOut.write(p.getBytes("UTF-8"));
+                    } finally {
+                        gzipOut.close();
+                    }
+                } else {
+                    // otherwise plaintext
+                    final PrintWriter pw = response.getWriter();
+                    pw.print(p);
+                    pw.flush();
+                }
+            } catch (JsonException e) {
+                logger.error("doPut: Got a JSONException: " + e, e);
+                response.sendError(500);
+            } catch (UndefinedClusterViewException e) {
+                logger.warn("doPut: no clusterView available at the moment - 
cannot handle connectors now: " + e);
+                response.sendError(503); // "please retry, but atm I can't 
help since I'm isolated"
             }
-            final String p = 
requestValidator.encodeMessage(replyAnnouncement.asJSON());
-            requestValidator.trustMessage(response, request, p);
-            // gzip the response if the client accepts this
-            final String acceptEncodingHeader = 
request.getHeader("Accept-Encoding");
-            if (acceptEncodingHeader != null && 
acceptEncodingHeader.contains("gzip")) {
-                // tell the client that the content is gzipped:
-                response.setHeader("Content-Encoding", "gzip");
-
-                // then gzip the body
-                final GZIPOutputStream gzipOut = new 
GZIPOutputStream(response.getOutputStream());
-                gzipOut.write(p.getBytes("UTF-8"));
-                gzipOut.close();
-            } else {
-                // otherwise plaintext
-                final PrintWriter pw = response.getWriter();
-                pw.print(p);
-                pw.flush();
+        } catch (IOException e) {
+            logger.error("doPut: IOException occurred: " + e, e);
+            try {
+                
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+            } catch (IOException e2) {
+                logger.error("doPut: IOException while sending error response: 
" + e2, e2);
+            }
+        } catch (Exception e) {
+            logger.error("doPut: Unexpected exception occurred: " + e, e);
+            try {
+                
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+            } catch (IOException e2) {
+                logger.error("doPut: IOException while sending error response: 
" + e2, e2);
             }
-        } catch (JsonException e) {
-            logger.error("doPost: Got a JSONException: " + e, e);
-            response.sendError(500);
-        } catch (UndefinedClusterViewException e) {
-            logger.warn("doPost: no clusterView available at the moment - 
cannot handle connectors now: " + e);
-            response.sendError(503); // "please retry, but atm I can't help 
since I'm isolated"
         }
     }
 

Reply via email to