PropagateError in triggerable service task with expression

Hi,

I have a triggerable service task which uses an expression to start an asynchronous background job, e.g.

<serviceTask id="init-job" name="init my async Job" activiti:async="true" activiti:expression="${bean.requestAsyncJob()}" activiti:resultVariableName="jobId" activiti:triggerable="true">
  <extensionElements>
    <activiti:executionListener event="end" delegateExpression="${evaluateCallback}" />
    <activiti:mapException errorCode="CODE-001">java.lang.RuntimeException</activiti:mapException>
  </extensionElements>
</serviceTask>

I want to catch an error (e.g. RuntimeException) by an Error Boundary Event attached to my init-job Service Task. This works, when the requestAsyncJob() Method throws some RuntimException.

But since it’s asynchronous, it’s also possible, that the external sytems sends us after the method completion a failure (we trigger() then the execution with a variable status=error), and we would also like to enter the Error Boundary Event. Currently we have some ‘Callback’ ExecutionListeners for examing the status variable and throwing exceptions when status=error so that the execution stops.

But throwing the RuntimeException in the ExecutionListener does not propagate the error, also calling ErrorPropagation.propagateError(“some-error”, execution) inside there does not work.

Any ideas how to come around this issue by using expressions (not delegateExpressions)?

Regards, Björn

ok, no reply, not sure, whether my question was unclear or too complicated !?

So, I found following working solution:

I extend org.flowable.engine.impl.bpmn.behavior.ServiceTaskExpressionActivityBehavior and overwrite trigger() by implementing the Error-propagation inside there.

Next problem: How to create a DeadLetter Job, when the callback is reportet as error (this does not happen)?

I tried following code, which is executed without exception but the DB table ACT_RU_DEADLETTER_JOB is empty:

public void trigger(DelegateExecution execution, String signalName, Object signalData) {
    .....
    JobService jobService = CommandContextUtil.getJobService();
    DeadLetterJobEntity job = jobService.createDeadLetterJob();
    job.setExecutionId(execution.getId());
    job.setProcessInstanceId(execution.getProcessInstanceId());
    job.setProcessDefinitionId(execution.getProcessDefinitionId());
    job.setElementId(execution.getCurrentFlowElement().getId());
    job.setElementName(execution.getCurrentFlowElement().getName());
    // Inherit tenant id (if applicable)
    if(execution.getTenantId() != null) {
        job.setTenantId(execution.getTenantId());
    }
    jobService.insertDeadLetterJob(job); 

Any idea, why the DB-Table is not populated? Transaction not committed?

Hoping for an answer this time,
Björn

I agree. If the error propagation isn’t done there, it should be added. I’ll check if I can add this to the code.

No, that code looks correct.

Can you enable debug logging and check whether either the deadletter job gets inserted (doubtful) or there is a transaction rollback? In the second case, the deadletter job should then be created in a post-rollback listener that you can attach to the currect TransactionContext (which you can retrieve via the Context class).

the problem was an exception thrown by me, so I guess it was caused by an rollback. I removed the throws part and it works now

would be great