diff --git a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/event/BpmnError.java b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/event/BpmnError.java
index e44ef6e6af114b90670b3251adc5d1928b64bc4a..6fd07d1a4fb3bcfa3b68d1dc8827f3d70afc54e9 100644
--- a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/event/BpmnError.java
+++ b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/event/BpmnError.java
@@ -39,6 +39,12 @@ public class BpmnError extends ActivitiException {
public BpmnError(String errorCode, String message) {
super(message);
+ if (errorCode == null) {
+ throw new ActivitiException("Error Code must not be null.");
+ }
+ if (errorCode.length() < 1) {
+ throw new ActivitiException("Error Code must not be empty.");
+ }
this.errorCode = errorCode;
}
diff --git a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/helper/ClassDelegate.java b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/helper/ClassDelegate.java
index 983be2a15eadb991711354ba30810d0a71e610b3..dda34bd8b9e01b067c73e3d3bd36af002c559fbe 100644
--- a/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/helper/ClassDelegate.java
+++ b/modules/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/helper/ClassDelegate.java
@@ -34,6 +34,7 @@ import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.delegate.ExecutionListenerInvocation;
import org.activiti.engine.impl.delegate.TaskListenerInvocation;
import org.activiti.engine.impl.pvm.PvmActivity;
+import org.activiti.engine.impl.pvm.PvmScope;
import org.activiti.engine.impl.pvm.delegate.ActivityBehavior;
import org.activiti.engine.impl.pvm.delegate.ActivityExecution;
import org.activiti.engine.impl.pvm.delegate.SignallableActivityBehavior;
@@ -120,25 +121,43 @@ public class ClassDelegate extends AbstractBpmnActivityBehavior implements TaskL
} catch (BpmnError error) {
// find error handler
PvmActivity errorEventHandler = null;
- for (PvmActivity activity : execution.getActivity().getActivities()) {
- if (((ActivityImpl) activity).getActivityBehavior() instanceof BoundaryEventActivityBehavior) {
- // TODO check error code of error handler
- errorEventHandler = activity;
- break;
+ // search for error handler with same error code as thrown Error
+ PvmScope scope = execution.getActivity();
+ while (errorEventHandler == null && scope != null) {
+ for (PvmActivity activity : scope.getActivities()) {
+ if (((ActivityImpl) activity).getActivityBehavior() instanceof BoundaryEventActivityBehavior
+ && error.getErrorCode().equals(activity.getProperty("errorCode"))) {
+ errorEventHandler = activity;
+ break;
+ }
+ }
+ // search for generic error handler if no error handler with that error code has been found
+ if (errorEventHandler == null) {
+ for (PvmActivity activity : scope.getActivities()) {
+ if (((ActivityImpl) activity).getActivityBehavior() instanceof BoundaryEventActivityBehavior
+ && (activity.getProperty("errorCode") == null || "".equals(activity.getProperty("errorCode")))) {
+ errorEventHandler = activity;
+ break;
+ }
+ }
+
+ }
+ // search for error handlers in parent scopes
+ if (errorEventHandler == null) {
+ if (scope instanceof PvmActivity) {
+ scope = ((PvmActivity) scope).getParent();
+ } else {
+ scope = null; // stop search
+ }
}
}
- // TODO search for error handlers in parent scopes
-
+
+ ErrorEndEventActivityBehavior errorEndEvent = new ErrorEndEventActivityBehavior(error.getErrorCode());
if (errorEventHandler != null) {
- // continue execution
- ErrorEndEventActivityBehavior errorEndEvent = new ErrorEndEventActivityBehavior(error.getErrorCode());
errorEndEvent.setBorderEventActivityId(errorEventHandler.getId());
- errorEndEvent.execute(execution);
- // execution.executeActivity(errorEventHandler);
- } else {
- // throw error up
- throw error;
}
+ // continue execution
+ errorEndEvent.execute(execution);
}
}
diff --git a/modules/activiti-engine/src/test/java/org/activiti/engine/test/bpmn/event/error/BoundaryErrorEventTest.java b/modules/activiti-engine/src/test/java/org/activiti/engine/test/bpmn/event/error/BoundaryErrorEventTest.java
index 3c46db72e58da5ec2dafe215096da82c71adfc4b..122e305eefbc7f546519c49062c652d2f163faa1 100644
--- a/modules/activiti-engine/src/test/java/org/activiti/engine/test/bpmn/event/error/BoundaryErrorEventTest.java
+++ b/modules/activiti-engine/src/test/java/org/activiti/engine/test/bpmn/event/error/BoundaryErrorEventTest.java
@@ -242,8 +242,50 @@ public class BoundaryErrorEventTest extends PluggableActivitiTestCase {
@Deployment
public void testCatchErrorThrownByJavaDelegateOnServiceTask() {
String procId = runtimeService.startProcessInstanceByKey("catchErrorThrownByJavaDelegateOnServiceTask").getId();
-
- // The service task will throw and error event,
+ assertThatErrorHasBeenCaught(procId);
+ }
+
+ @Deployment
+ public void testCatchErrorThrownByJavaDelegateOnServiceTaskWithErrorCode() {
+ String procId = runtimeService.startProcessInstanceByKey("catchErrorThrownByJavaDelegateOnServiceTaskWithErrorCode").getId();
+ assertThatErrorHasBeenCaught(procId);
+ }
+
+ @Deployment
+ public void testCatchErrorThrownByJavaDelegateOnEmbeddedSubProcess() {
+ String procId = runtimeService.startProcessInstanceByKey("catchErrorThrownByJavaDelegateOnEmbeddedSubProcess").getId();
+ assertThatErrorHasBeenCaught(procId);
+ }
+
+ @Deployment
+ public void testCatchErrorThrownByJavaDelegateOnEmbeddedSubProcessInduction() {
+ String procId = runtimeService.startProcessInstanceByKey("catchErrorThrownByJavaDelegateOnEmbeddedSubProcessInduction").getId();
+ assertThatErrorHasBeenCaught(procId);
+ }
+
+ @Deployment(resources = {
+ "org/activiti/engine/test/bpmn/event/error/BoundaryErrorEventTest.testCatchErrorThrownByJavaDelegateOnCallActivity-parent.bpmn20.xml",
+ "org/activiti/engine/test/bpmn/event/error/BoundaryErrorEventTest.testCatchErrorThrownByJavaDelegateOnCallActivity-child.bpmn20.xml"
+ })
+ public void testCatchErrorThrownByJavaDelegateOnCallActivity() {
+ String procId = runtimeService.startProcessInstanceByKey("catchErrorThrownByJavaDelegateOnCallActivity-parent").getId();
+ assertThatErrorHasBeenCaught(procId);
+ }
+
+ @Deployment(resources = {
+ "org/activiti/engine/test/bpmn/event/error/BoundaryErrorEventTest.testUncaughtErrorThrownByJavaDelegateOnCallActivity-parent.bpmn20.xml",
+ "org/activiti/engine/test/bpmn/event/error/BoundaryErrorEventTest.testCatchErrorThrownByJavaDelegateOnCallActivity-child.bpmn20.xml"
+ })
+ public void testUncaughtErrorThrownByJavaDelegateOnCallActivity() {
+ try {
+ runtimeService.startProcessInstanceByKey("uncaughtErrorThrownByJavaDelegateOnCallActivity-parent");
+ } catch (ActivitiException e) {
+ assertTextPresent("No catching boundary event found for error with errorCode '23', neither in same process nor in parent process", e.getMessage());
+ }
+ }
+
+ private void assertThatErrorHasBeenCaught(String procId) {
+ // The service task will throw an error event,
// which is caught on the service task boundary
assertEquals("No tasks found in task list.", 1, taskService.createTaskQuery().count());
Task task = taskService.createTaskQuery().singleResult();
@@ -253,5 +295,5 @@ public class BoundaryErrorEventTest extends PluggableActivitiTestCase {
taskService.complete(task.getId());
assertProcessEnded(procId);
}
-
+
}
diff --git a/modules/activiti-engine/src/test/resources/org/activiti/engine/test/bpmn/event/error/BoundaryErrorEventTest.testCatchErrorThrownByJavaDelegateOnCallActivity-child.bpmn20.xml b/modules/activiti-engine/src/test/resources/org/activiti/engine/test/bpmn/event/error/BoundaryErrorEventTest.testCatchErrorThrownByJavaDelegateOnCallActivity-child.bpmn20.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3cf9bdbaa11c01702b0029c010d984e01fb24a8f
--- /dev/null
+++ b/modules/activiti-engine/src/test/resources/org/activiti/engine/test/bpmn/event/error/BoundaryErrorEventTest.testCatchErrorThrownByJavaDelegateOnCallActivity-child.bpmn20.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/modules/activiti-engine/src/test/resources/org/activiti/engine/test/bpmn/event/error/BoundaryErrorEventTest.testCatchErrorThrownByJavaDelegateOnCallActivity-parent.bpmn20.xml b/modules/activiti-engine/src/test/resources/org/activiti/engine/test/bpmn/event/error/BoundaryErrorEventTest.testCatchErrorThrownByJavaDelegateOnCallActivity-parent.bpmn20.xml
new file mode 100644
index 0000000000000000000000000000000000000000..06fc3fbe8611f9c91d9b635012ad41cc4223fcc4
--- /dev/null
+++ b/modules/activiti-engine/src/test/resources/org/activiti/engine/test/bpmn/event/error/BoundaryErrorEventTest.testCatchErrorThrownByJavaDelegateOnCallActivity-parent.bpmn20.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/modules/activiti-engine/src/test/resources/org/activiti/engine/test/bpmn/event/error/BoundaryErrorEventTest.testCatchErrorThrownByJavaDelegateOnEmbeddedSubProcess.bpmn20.xml b/modules/activiti-engine/src/test/resources/org/activiti/engine/test/bpmn/event/error/BoundaryErrorEventTest.testCatchErrorThrownByJavaDelegateOnEmbeddedSubProcess.bpmn20.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b9c71faf72027895bac6b874f7ebfa52f1d5bec8
--- /dev/null
+++ b/modules/activiti-engine/src/test/resources/org/activiti/engine/test/bpmn/event/error/BoundaryErrorEventTest.testCatchErrorThrownByJavaDelegateOnEmbeddedSubProcess.bpmn20.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/modules/activiti-engine/src/test/resources/org/activiti/engine/test/bpmn/event/error/BoundaryErrorEventTest.testCatchErrorThrownByJavaDelegateOnEmbeddedSubProcessInduction.bpmn20.xml b/modules/activiti-engine/src/test/resources/org/activiti/engine/test/bpmn/event/error/BoundaryErrorEventTest.testCatchErrorThrownByJavaDelegateOnEmbeddedSubProcessInduction.bpmn20.xml
new file mode 100644
index 0000000000000000000000000000000000000000..9aba693a750f1efe177236cb6f6264e802d6bb1a
--- /dev/null
+++ b/modules/activiti-engine/src/test/resources/org/activiti/engine/test/bpmn/event/error/BoundaryErrorEventTest.testCatchErrorThrownByJavaDelegateOnEmbeddedSubProcessInduction.bpmn20.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/modules/activiti-engine/src/test/resources/org/activiti/engine/test/bpmn/event/error/BoundaryErrorEventTest.testCatchErrorThrownByJavaDelegateOnServiceTask.bpmn20.xml b/modules/activiti-engine/src/test/resources/org/activiti/engine/test/bpmn/event/error/BoundaryErrorEventTest.testCatchErrorThrownByJavaDelegateOnServiceTask.bpmn20.xml
index b5f4aaa113d91ffe045f1974b0a26a6dab68bcee..58d306bb21f07701e17c53af7a3039a5125aa8df 100644
--- a/modules/activiti-engine/src/test/resources/org/activiti/engine/test/bpmn/event/error/BoundaryErrorEventTest.testCatchErrorThrownByJavaDelegateOnServiceTask.bpmn20.xml
+++ b/modules/activiti-engine/src/test/resources/org/activiti/engine/test/bpmn/event/error/BoundaryErrorEventTest.testCatchErrorThrownByJavaDelegateOnServiceTask.bpmn20.xml
@@ -12,7 +12,7 @@
-
+
diff --git a/modules/activiti-engine/src/test/resources/org/activiti/engine/test/bpmn/event/error/BoundaryErrorEventTest.testCatchErrorThrownByJavaDelegateOnServiceTaskWithErrorCode.bpmn20.xml b/modules/activiti-engine/src/test/resources/org/activiti/engine/test/bpmn/event/error/BoundaryErrorEventTest.testCatchErrorThrownByJavaDelegateOnServiceTaskWithErrorCode.bpmn20.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b67aeca61f1390ab819334ab75d7070a611b77a2
--- /dev/null
+++ b/modules/activiti-engine/src/test/resources/org/activiti/engine/test/bpmn/event/error/BoundaryErrorEventTest.testCatchErrorThrownByJavaDelegateOnServiceTaskWithErrorCode.bpmn20.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/modules/activiti-engine/src/test/resources/org/activiti/engine/test/bpmn/event/error/BoundaryErrorEventTest.testUncaughtErrorThrownByJavaDelegateOnCallActivity-parent.bpmn20.xml b/modules/activiti-engine/src/test/resources/org/activiti/engine/test/bpmn/event/error/BoundaryErrorEventTest.testUncaughtErrorThrownByJavaDelegateOnCallActivity-parent.bpmn20.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8329e3ff9d1fadf2e78635645dc9a96e1382e119
--- /dev/null
+++ b/modules/activiti-engine/src/test/resources/org/activiti/engine/test/bpmn/event/error/BoundaryErrorEventTest.testUncaughtErrorThrownByJavaDelegateOnCallActivity-parent.bpmn20.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file