cancel
Showing results for 
Search instead for 
Did you mean: 

activiti:delegateExpression: BpmnError not caught

workflowuser2
Champ in-the-making
Champ in-the-making
Hi,

I have a subprocess and a boundary error event on the subprocess scope. Now, in the subprocess, I have service tasks with activiti:delegateExpression. In these java delegates, if I throw BpmnError, it is never caught and processed.

The same process works if I use java delegates (activiti:class="java.delegate.class") instead of activiti:delegateExpression.
In the regular java delegate case, I observed, org.activiti.engine.impl.bpmn.helper.ClassDelegate wraps ServiceTaskJavaDelegateActivityBehavior and process BpmnError:
try {
      activityBehaviorInstance.execute(execution);
    } catch (BpmnError error) {
      ErrorPropagation.propagateError(error, execution);
    }

However, ServiceTaskDelegateExpressionActivityBehavior call does not go through ClassDelegate and therefore does not handle BpmnError.

I hope the above information is enough to understand the bug. Since I am using OSGi, it is difficult to attach unit test.
Please let me know if I am missing something.

Process xml:

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlnsSmiley Surprisedmgdc="http://www.omg.org/spec/DD/20100524/DC" xmlnsSmiley Surprisedmgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
  <process id="applyProfile" name="Apply Profile">
 
 
    <startEvent id="startevent1" name="Start"></startEvent>
    <endEvent id="endevent1" name="End"></endEvent>
   
    <sequenceFlow id="flow1" name="" sourceRef="startevent1" targetRef="mainProcess"></sequenceFlow>
    <sequenceFlow id="flow2" name="" sourceRef="mainProcess" targetRef="endevent1"></sequenceFlow>
   
    <subProcess id="mainProcess">
       <startEvent id="subProcessStart" />
       <endEvent id="subProcessEnd" />
       <serviceTask id="step1" name="step1WithError" activiti:delegateExpression="${main1Delegate}"></serviceTask>
       <serviceTask id="step2" name="step2" activiti:class="com.acme.delegates.Main2Delegate"></serviceTask>
       <sequenceFlow id="flow11" sourceRef="subProcessStart" targetRef="step1" />
       <sequenceFlow id="flow12" sourceRef="step1" targetRef="step2" />
       <sequenceFlow id="flow13" sourceRef="ApplyProfile" targetRef="subProcessEnd" />
   </subProcess>
  
   <serviceTask id="errorTask" name="Global error handling" activiti:class="com.acme.delegates.Main1Delegate"></serviceTask>
    <endEvent id="errorEnd" />
    <sequenceFlow id="flow_error1" sourceRef="errorEvent" targetRef="errorTask" />
    <sequenceFlow id="flow_error2" sourceRef="errorTask" targetRef="errorEnd" />
   
   <boundaryEvent id="errorEvent" attachedToRef="mainProcess">
      <errorEventDefinition/>
   </boundaryEvent>
   
  </process>
</serviceTask> –>
 
</definitions>


main1Delegate is an OSGi service (also JavaDelegate). Now, in this java delegate, if I throw BpmnError, it is never caught and error flow is not activated.
8 REPLIES 8

frederikherema1
Star Contributor
Star Contributor
As of 5.10 (due in august), this is supported. Current trunk of ServiceTaskDelegateExpressionActivityBehavior contains:


} catch (Exception exc) {

      Throwable cause = exc;
      BpmnError error = null;
      while (cause != null) {
        if (cause instanceof BpmnError) {
          error = (BpmnError) cause;
          break;
        }
        cause = cause.getCause();
      }

      if (error != null) {
        ErrorPropagation.propagateError(error, execution);
      } else {
        throw exc;
      }

    }

This was fixed this month for http://jira.codehaus.org/browse/ACT-1159. But thanks for reporting this!

pfalcon
Champ in-the-making
Champ in-the-making
I have compiled from 5.10-tag and now BpmnError is caught. However executions processed on error path don't ended, so a process seams as not ended.
In reality all task and a process are ended. However not all DB data are moved to historical tables, and according to API some tasks and a process are not ended.

My process:

  <process id="multiSubProcess">
    <startEvent id="sid-D59EFC88-5697-4ED8-87A2-53FDDFF403AA"></startEvent>
    <subProcess id="bookSubProcess" name="Book Domain">
      <multiInstanceLoopCharacteristics isSequential="false" activiti:collection="orderItemCol" activiti:elementVariable="orderItem"></multiInstanceLoopCharacteristics>
      <startEvent id="start" name="Start"></startEvent>
      <serviceTask id="bookDomain" name="Book" activiti:expression="#{multiSubProcess.bookDomain(processError, orderItem)}"></serviceTask>
      <boundaryEvent id="boundaryerror4" cancelActivity="false" attachedToRef="bookDomain">
        <errorEventDefinition></errorEventDefinition>
      </boundaryEvent>
      <endEvent id="end" name="End"></endEvent>
      <serviceTask id="validateDomain" name="Validate" activiti:expression="#{multiSubProcess.validateOrderElem(processError, orderItem)}"></serviceTask>
      <boundaryEvent id="boundaryerror2" name="" cancelActivity="false" attachedToRef="validateDomain">
        <errorEventDefinition></errorEventDefinition>
      </boundaryEvent>
      <endEvent id="endevent1" name="End"></endEvent>
      <sequenceFlow id="flow3" name="" sourceRef="bookDomain" targetRef="end"></sequenceFlow>
      <sequenceFlow id="flow4" name="" sourceRef="start" targetRef="validateDomain"></sequenceFlow>
      <sequenceFlow id="flow5" name="" sourceRef="validateDomain" targetRef="bookDomain"></sequenceFlow>
    </subProcess>
    <endEvent id="sid-4F5FE891-7E26-445F-9324-416B5E244D8B"></endEvent>
    <sequenceFlow id="flow6" name="" sourceRef="sid-D59EFC88-5697-4ED8-87A2-53FDDFF403AA" targetRef="bookSubProcess"></sequenceFlow>
    <sequenceFlow id="flow7" name="" sourceRef="bookSubProcess" targetRef="sid-4F5FE891-7E26-445F-9324-416B5E244D8B"></sequenceFlow>
    <sequenceFlow id="flow8" name="" sourceRef="boundaryerror2" targetRef="endevent1"></sequenceFlow>
    <sequenceFlow id="flow9" name="" sourceRef="boundaryerror4" targetRef="endevent1"></sequenceFlow>
  </process>

bernd_ruecker
Champ in-the-making
Champ in-the-making
Do you have a testcase for that?

bernd_ruecker
Champ in-the-making
Champ in-the-making
Hmm, you have set the boundary event to "cancelActivity="false"", which means the process is not ended. If you change that to true the behavior should change. Could you please double check that and come back with more detailed information if it still doesn't work as expected?

Thanks.

pfalcon
Champ in-the-making
Champ in-the-making
Thanks.

After change "cancelActivity=true" a process and its all tasks are ended, so it works as expected.

But this setting (false) is default for boundary error in ActivitiDesigner.
After all throwing a BpmnError should automatically cancel an activity, shouldn't it?

bernd_ruecker
Champ in-the-making
Champ in-the-making
Basically by BPMN it is intenially left to the user to decide, that's why you have to model it. Changing the default in the Activiti Designer might be an improvement indeed, you could open a jira for this and select the component designer (as we with camunda fox have a different designer which does the canceling one as default already, I am personally not really eager to do it ;-)).

fabttl
Champ in-the-making
Champ in-the-making
Hello,

I have the same problem, and setting cancelActivity="true" resolved it.

But, what about the previous PI in the database based on the previous BPMN with the cancelActivity="false" ?

How should I "close/cancel/finish" the previous PIs ?
Are there any APIs ?
Should I use SQL queries ?

Thank you for any ideas that could help me Smiley Happy

FRO

bernd_ruecker
Champ in-the-making
Champ in-the-making
There are API's to either cancel (see RuntimeService.delete…) or even upgrade the version for instances (see https://app.camunda.com/confluence/display/foxUserGuide/Process+Versioning). So there are different possibilities to achieve that.