Author: alex.guizar(a)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<...
+ */
+ 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());
+ }
}