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

lukaszlenart pushed a commit to branch feature/WW-5414-after
in repository https://gitbox.apache.org/repos/asf/struts.git

commit 0141068ff4a5e0c32441fe9895717e88fbf2521b
Author: Lukasz Lenart <lukaszlen...@apache.org>
AuthorDate: Sat May 11 08:23:56 2024 +0200

    WW-5414 Always call afterInvocation even in case of exception
---
 .../interceptor/exec/StrutsBackgroundProcess.java  | 16 ++++++++---
 .../exec/StrutsBackgroundProcessTest.java          | 32 ++++++++++++++++++++++
 2 files changed, 44 insertions(+), 4 deletions(-)

diff --git 
a/core/src/main/java/org/apache/struts2/interceptor/exec/StrutsBackgroundProcess.java
 
b/core/src/main/java/org/apache/struts2/interceptor/exec/StrutsBackgroundProcess.java
index 42237262f..dce78730c 100644
--- 
a/core/src/main/java/org/apache/struts2/interceptor/exec/StrutsBackgroundProcess.java
+++ 
b/core/src/main/java/org/apache/struts2/interceptor/exec/StrutsBackgroundProcess.java
@@ -20,6 +20,8 @@ package org.apache.struts2.interceptor.exec;
 
 import com.opensymphony.xwork2.ActionContext;
 import com.opensymphony.xwork2.ActionInvocation;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
 
 import java.io.Serializable;
 
@@ -30,6 +32,8 @@ public class StrutsBackgroundProcess implements 
BackgroundProcess, Serializable
 
     private static final long serialVersionUID = 3884464776311686443L;
 
+    private static final Logger LOG = 
LogManager.getLogger(StrutsBackgroundProcess.class);
+
     private final String threadName;
     private final int threadPriority;
 
@@ -44,8 +48,8 @@ public class StrutsBackgroundProcess implements 
BackgroundProcess, Serializable
     /**
      * Constructs a background process
      *
-     * @param invocation The action invocation
-     * @param threadName The name of background thread
+     * @param invocation     The action invocation
+     * @param threadName     The name of background thread
      * @param threadPriority The priority of background thread
      */
     public StrutsBackgroundProcess(ActionInvocation invocation, String 
threadName, int threadPriority) {
@@ -61,11 +65,15 @@ public class StrutsBackgroundProcess implements 
BackgroundProcess, Serializable
                 try {
                     beforeInvocation();
                     result = invocation.invokeActionOnly();
-                    afterInvocation();
                 } catch (Exception e) {
+                    try {
+                        afterInvocation();
+                    } catch (Exception ex) {
+                        LOG.warn("Exception during afterInvocation() 
execution", ex);
+                    }
                     exception = e;
                 } finally {
-                  done = true;
+                    done = true;
                 }
             });
             processThread.setName(threadName);
diff --git 
a/core/src/test/java/org/apache/struts2/interceptor/exec/StrutsBackgroundProcessTest.java
 
b/core/src/test/java/org/apache/struts2/interceptor/exec/StrutsBackgroundProcessTest.java
index 5906c995a..1e0166951 100644
--- 
a/core/src/test/java/org/apache/struts2/interceptor/exec/StrutsBackgroundProcessTest.java
+++ 
b/core/src/test/java/org/apache/struts2/interceptor/exec/StrutsBackgroundProcessTest.java
@@ -120,6 +120,19 @@ public class StrutsBackgroundProcessTest extends 
StrutsInternalTestCase {
         assertEquals(100, mutableState.get());
     }
 
+    public void testErrorableProcesses() throws InterruptedException {
+        MockActionInvocationWithActionInvoker invocation = new 
MockActionInvocationWithActionInvoker(() -> {
+            throw new IllegalStateException("boom");
+        });
+
+        BackgroundProcess bp = new ErrorableBackgroundProcess(invocation, 
"error").prepare();
+        executor.execute(bp);
+
+        Thread.sleep(100);
+
+        assertTrue("afterInvocation not called in case of exception", 
((ErrorableBackgroundProcess) bp).isDoneAfter());
+    }
+
     public void testUnpreparedProcess() throws ExecutionException, 
InterruptedException, TimeoutException {
         // given
         MockActionInvocationWithActionInvoker invocation = new 
MockActionInvocationWithActionInvoker(() -> "done");
@@ -177,3 +190,22 @@ class LockBackgroundProcess extends 
StrutsBackgroundProcess {
         lock.notify();
     }
 }
+
+class ErrorableBackgroundProcess extends StrutsBackgroundProcess {
+
+    private boolean doneAfter;
+
+    public ErrorableBackgroundProcess(ActionInvocation invocation, String 
name) {
+        super(invocation, name, Thread.NORM_PRIORITY);
+    }
+
+    @Override
+    protected void afterInvocation() throws Exception {
+        super.afterInvocation();
+        doneAfter = true;
+    }
+
+    public boolean isDoneAfter() {
+        return doneAfter;
+    }
+}

Reply via email to