cancel
Showing results for 
Search instead for 
Did you mean: 

Exception Handling of Asynchronous Processes

flavio_donze
Champ in-the-making
Champ in-the-making
Hello

After the discussion here http://forums.activiti.org/en/viewtopic.php?f=6&t=6334 about transaction deadlocks, I ended up setting my callActivity activiti:async="true".
This solved my deadlock problem, but now I'm facing the problem of handling exceptions.

The workflow that caused the deadlocks, does not have any user interaction, it consists of a bunch of serviceTasks.
Before adding the async="true", in case one of the serviceTasks threw an exception it was caught by the client and displayed in a message box.
The whole transaction was rollbacked and no workflow was stored in the database.
Using the async="true", the client does not get notified if something went wrong, since the workflow is running asynchronous on the server.
d
I found this in the documentation: http://activiti.org/userguide/index.html#serviceTaskExceptionHandling
But this won't fit my usecase, I dont want to have an outgoing "exception" sequenceFlow for every service task, plus it won't work because the transaction is marked for rollback.

This is one of my service tasks, for all service tasks I use my own com.softmodeler.workflow.OSGiLookup.
Right now I catch the exception in the implemented JavaDelegate.execute(DelegateExecution execution), at this point the transaction is already marked for rollback.
I can not redirect the process since it will have no effekt after the rollback, so right now I'm creating and sending an error mail to the initiator of the workflow.
As I mentioned earlier, before the workflow was asynchronous, the exception was directly displayed to the user.

      <serviceTask id="storeRepository" activiti:class="com.softmodeler.workflow.OSGiLookup">
         <extensionElements>
             <activiti:field name="serviceName" expression="com.softmodeler.service.IRepositoryService"/>
             <activiti:field name="methodName" stringValue="storeProductiveObject"/>
             <activiti:field name="objectId" expression="${objectId}"/>
             <activiti:field name="param1" expression="${version}"/>
         </extensionElements>
      </serviceTask>

So I was wondering maybe there is a "standard" way to handle this?
Maybe an exception or fail listener on the overall workflow.
How do other people handle exceptions in asynchronous workflows?

Also now I get three mails, since the job executor tries three times to execute the workflow.
Is it possible to disable this behaviour?

greets
Flavio
6 REPLIES 6

jbarrez
Star Contributor
Star Contributor
The problem is that you don't really know when the execution will actually happen.
If the load is high, it might even take a while before it is picked up by the job executor.

I think you need to ask yourself what would be the wanted behavior:
- Do you want to show it in the UI directly? If so, we will have to dig deeper in why the deadlock happens
- Is email sending enough?
- Do you want to create a dedicated UI for failed processes?

Also now I get three mails, since the job executor tries three times to execute the workflow.
Is it possible to disable this behaviour?

Yes: by default there is a retry interceptor configured when you execute any API call (and thus a Command).
You can remove this interceptor, change or tweak it. Or add your own.

Similarly you could add your own interceptor that does something with the exception that happens during process execution.
That way you can catch it (even when its done async) and do something accordingly.

flavio_donze
Champ in-the-making
Champ in-the-making
Hi jbarrez

Thanks for your reply!

If we could get rid of the deadlock, showing the exception in the UI would be a good option. This is how I have it right now.
I have added a test case in the deadlock thread: http://forums.activiti.org/en/viewtopic.php?f=6&t=6334&p=23640
Otherwise sending an email is an ok solution.

I looked into the retry interceptor and found these two classes org.activiti.engine.impl.interceptor.RetryInterceptor and org.activiti.engine.impl.interceptor.JtaRetryInterceptor.
I did set breakpoints all over those classes but I never enter it, I also did not find any other place where this handling could be done.
Could you point me to the right class?
Is there some documentation about this?

greets and thanks for your help
Flavio

jbarrez
Star Contributor
Star Contributor
<i>Could you point me to the right class?</i>

I checked and you are indeed right. The retry interceptor is not set by default.
But I then remembered it has to do with jobs: jobs have a retries fields that is decreased when a job execution fails.

<i>Is there some documentation about this?</i>

No, I'm sorry. That stuff could indeed use docs. I put it on my todo list.

flavio_donze
Champ in-the-making
Champ in-the-making
I came across http://jira.codehaus.org/browse/ACT-1046, I think the FailedJobCommandFactory is what I was looking for.

I will have a look at it and report back.

flavio_donze
Champ in-the-making
Champ in-the-making

frederikherema1
Star Contributor
Star Contributor
Thanks for sharing your experiences!