[jbpm-commits] JBoss JBPM SVN: r6589 - in jbpm3/branches/jbpm-3.2-soa/modules/core/src: test/java/org/jbpm/graph/def and 1 other directory.

do-not-reply at jboss.org do-not-reply at jboss.org
Thu Aug 12 21:10:30 EDT 2010


Author: alex.guizar at jboss.com
Date: 2010-08-12 21:10:29 -0400 (Thu, 12 Aug 2010)
New Revision: 6589

Modified:
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/def/GraphElement.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/graph/def/ExceptionHandlerTest.java
Log:
JBPM-2854 clear exception from executionContext after handling it, allowing executionContext to handle further exceptions

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/def/GraphElement.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/def/GraphElement.java	2010-08-12 10:18:37 UTC (rev 6588)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/def/GraphElement.java	2010-08-13 01:10:29 UTC (rev 6589)
@@ -229,7 +229,8 @@
       if (!action.acceptsPropagatedEvents() && isPropagated) continue;
 
       if (action.isAsync()) {
-        ExecuteActionJob job = createAsyncActionExecutionJob(executionContext.getToken(), action);
+        ExecuteActionJob job = createAsyncActionExecutionJob(executionContext.getToken(),
+          action);
         MessageService messageService = executionContext.getJbpmContext()
           .getServices()
           .getMessageService();
@@ -333,21 +334,28 @@
    */
   public void raiseException(Throwable exception, ExecutionContext executionContext) {
     if (isAbleToHandleExceptions(executionContext)) {
-      try {
-        ExceptionHandler exceptionHandler = findExceptionHandler(exception);
-        if (exceptionHandler != null) {
-          executionContext.setException(exception);
+      ExceptionHandler exceptionHandler = findExceptionHandler(exception);
+      // was a matching exception handler found?
+      if (exceptionHandler != null) {
+        // make exception available to handler
+        executionContext.setException(exception);
+        try {
           exceptionHandler.handleException(this, executionContext);
           return;
         }
+        catch (Exception e) {
+          // NOTE that Errors are not caught because that might halt the JVM
+          // and mask the original Error
+          exception = e;
+        }
+        finally {
+          // clear exception after handling it, allowing execution to handle further exceptions
+          // see https://jira.jboss.org/browse/JBPM-2854
+          executionContext.setException(null);
+        }
       }
-      catch (Exception e) {
-        // NOTE that Error's are not caught because that might halt the JVM
-        // and mask the original Error.
-        exception = e;
-      }
 
-      // if this graph element has parent
+      // if this graph element is not parentless
       GraphElement parent = getParent();
       if (parent != null && !equals(parent)) {
         // propagate exception to parent
@@ -356,7 +364,7 @@
       }
     }
 
-    // if exception was not handled, throw delegation exception to client
+    // if exception was not handled, throw delegation exception at client
     throw exception instanceof JbpmException ? (JbpmException) exception
       : new DelegationException("no applicable exception handler found", exception);
   }
@@ -369,18 +377,14 @@
    * </ul>
    */
   private static boolean isAbleToHandleExceptions(ExecutionContext executionContext) {
-    /*
-     * if an exception is already set, we are already handling an exception; in this case don't
-     * give the exception to the handlers but throw it to the client see
-     * https://jira.jboss.org/jira/browse/JBPM-1887
-     */
+    // if executionContext has an exception set, it is already handling an exception
+    // in this case, do not offer exception to handlers; throw at client
+    // see https://jira.jboss.org/jira/browse/JBPM-1887
     if (executionContext.getException() != null) return false;
 
-    /*
-     * check whether the transaction is still active before scanning the exception handlers.
-     * that way we can load the exception handlers lazily see
-     * https://jira.jboss.org/jira/browse/JBPM-1775
-     */
+    // check whether transaction is still active before scanning exception handlers
+    // this way, the exception handlers can be loaded lazily
+    // see https://jira.jboss.org/jira/browse/JBPM-1775
     JbpmContext jbpmContext = executionContext.getJbpmContext();
     if (jbpmContext != null) {
       Service service = jbpmContext.getServices().getPersistenceService();

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/graph/def/ExceptionHandlerTest.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/graph/def/ExceptionHandlerTest.java	2010-08-12 10:18:37 UTC (rev 6588)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/graph/def/ExceptionHandlerTest.java	2010-08-13 01:10:29 UTC (rev 6589)
@@ -136,4 +136,53 @@
     // exception is handled correctly
     assertTrue("expected " + pi + " to have ended", pi.hasEnded());
   }
+
+  /**
+   * If exception handlers are defined in multiple nodes, only the first one is triggered
+   * during one execution.
+   * 
+   * @see <a href="https://jira.jboss.org/browse/JBPM-2854">JBPM-2854</a>
+   */
+  public void testMultipleExceptionHandler() {
+    String xml = "<?xml version='1.0' encoding='UTF-8'?>" +
+        "<process-definition name='TestException'>" +
+        "   <start-state name='start'>" +
+        "      <transition to='node1' />" +
+        "   </start-state>   " +
+        "   <node name='node1'>" +        
+        "      <event type='node-enter'>" +
+        "         <script>executionContext.setVariable(\"count\", 0)</script>" +
+        "         <action class='" +
+        ThrowExceptionAction.class.getName() +
+        "' />" +
+        "      </event>" +
+        "      <exception-handler>" +
+        "         <script>executionContext.setVariable(\"count\", count + 1)</script>" +
+        "      </exception-handler>" +
+        "      <transition to='node2' />" +
+        "   </node>" +
+        "   <node name='node2'>" +
+        "      <event type='node-enter'>" +
+        "         <action class='" +
+        ThrowExceptionAction.class.getName() +
+        "' />" +
+        "      </event>" +
+        "      <exception-handler>" +
+        "         <script>executionContext.setVariable(\"count\", count + 1)</script>" +
+        "      </exception-handler>" +
+        "      <transition to='end' />" +
+        "   </node>" +
+        "   <end-state name='end' />" +
+        "</process-definition>";
+
+    ProcessDefinition def = ProcessDefinition.parseXmlString(xml);
+    ProcessInstance pi = def.createProcessInstance();
+
+    // should not throw DelegationException
+    pi.signal();
+
+    // two exceptions are handled
+    Integer count = (Integer) pi.getContextInstance().getVariable("count");
+    assertEquals(2, count.intValue());
+  }
 }



More information about the jbpm-commits mailing list