Exception Handling Service Task

Hi,

I am using Flowable 6.5.0 and integrated Flowable via Spring boot.

I have created a simple business process where i have got couple of service tasks. In case of any exception in Service Task A, I am throwing a Runtime exception. I have added a variable named “STATUS” to reflect whether the process is PENDING, SUCCESS or FAILURE. The process starts with a PENDING status and moves on to SUCCESS or FAILURE. In case of failure, i update the STATUS variable to FAILURE and throw a Run-time Exception. .I understand throwing a Run-time Exception rolls back the complete transaction and the status variable wouldn’t hold the FAILURE value. The job will be moved to dead letter queue table.

If throw a BpmnError, i am able to update my engine variable and pass the engine variable to a REST API. i believe i wouldn’t be able to re-trigger the job, since the job will not be in dead letter queue table.

Is there a way where in case of technical failure, i can update the engine variable to FAILURE and pass the info to another REST API and still move the job to a dead letter queue to retry the job later.

Thanks
Karthik

1 Like

@joram, @wwitt

Could you please give any pointers for the above .

Thanks
Karthik

I’m not aware of anything built in to handle that. It seems that both continuing the process and moving the job to the dead letter queue would leave the process in an inconsistent state. Information about the previous execution is available to asynchronous service tasks. For instance, this code:

@Component
public class AsyncTask implements JavaDelegate {

    static Logger logger = LoggerFactory.getLogger(AsyncTask.class);

    final ProcessEngine processEngine;


    public AsyncTask(ProcessEngine processEngine) {
        this.processEngine = processEngine;
    }


    @Override
    public void execute(DelegateExecution delegateExecution) {
        JobService jobService = processEngine.getProcessEngineConfiguration().getAsyncExecutor().getJobServiceConfiguration().getJobService();

        List<Job> jobs = jobService.createJobQuery()
                .processInstanceId(delegateExecution.getProcessInstanceId())
                .list();

        jobs.forEach(job -> {
            logger.info("Job Retries: {}", job.getRetries());
            logger.info("Job Exception Message: {}", job.getExceptionMessage());
        });

        throw new FlowableException("Your mother was a hamster and your father smelt of elderberries!");
    }
}

Gives the output:


2020-10-31 08:41:28.996  INFO 3386 --- [           main] c.e.flowabler.demo.DemoApplication       : Started DemoApplication in 5.615 seconds (JVM running for 6.088)
2020-10-31 08:41:29.030  INFO 3386 --- [         task-1] com.example.flowabler.demo.AsyncTask     : Job Retries: 3
2020-10-31 08:41:29.030  INFO 3386 --- [         task-1] com.example.flowabler.demo.AsyncTask     : Job Exception Message: null
2020-10-31 08:41:29.036 ERROR 3386 --- [         task-1] ltAsyncRunnableExecutionExceptionHandler : Job c7650e36-1b7e-11eb-a455-826c3f5d847c failed

org.flowable.common.engine.api.FlowableException: Your mother was a hamster and your father smelt of elderberries!
...

2020-10-31 08:41:48.284  INFO 3386 --- [         task-2] com.example.flowabler.demo.AsyncTask     : Job Retries: 2
2020-10-31 08:41:48.284  INFO 3386 --- [         task-2] com.example.flowabler.demo.AsyncTask     : Job Exception Message: Your mother was a hamster and your father smelt of elderberries!
2020-10-31 08:41:48.285 ERROR 3386 --- [         task-2] ltAsyncRunnableExecutionExceptionHandler : Job c7650e36-1b7e-11eb-a455-826c3f5d847c failed

org.flowable.common.engine.api.FlowableException: Your mother was a hamster and your father smelt of elderberries!
...

2020-10-31 08:42:08.296  INFO 3386 --- [         task-3] com.example.flowabler.demo.AsyncTask     : Job Retries: 1
2020-10-31 08:42:08.296  INFO 3386 --- [         task-3] com.example.flowabler.demo.AsyncTask     : Job Exception Message: Your mother was a hamster and your father smelt of elderberries!
2020-10-31 08:42:08.297 ERROR 3386 --- [         task-3] ltAsyncRunnableExecutionExceptionHandler : Job c7650e36-1b7e-11eb-a455-826c3f5d847c failed

org.flowable.common.engine.api.FlowableException: Your mother was a hamster and your father smelt of elderberries!
...

You could use this information to send a message or signal. It may then be possible to model the process in a way that maintains its state and puts the job in the DLQ.

Will

Hey @Karthik,

You can try using the event listeners to achieve what you need. Instead of sending the variable in your service you can do it in the listeners:

You can listen on

  • FlowableEngineEventType#JOB_EXECUTION_SUCCESS - to set the variable to SUCCESS
  • FlowableEngineEventType#JOB_RETRIES_DECREMENTED - to set the variable to FAILURE if the job is a dead letter job

Cheers,
Filip

1 Like

Thank you @wwitt, @joram,

I have designed the process as below. I am throwing a Bpmnerror to a exception task where i am doing all my updates.I set the status to FAILURE. Then invoking the same task again and throwing a FlowableException if the status is FAILURE. This kind of works for me…