cancel
Showing results for 
Search instead for 
Did you mean: 

Catch Java ServiceTask exceptions using errorEventDefinition

kaech
Champ in-the-making
Champ in-the-making
My process incorporates a Java ServiceTask which throws an exception in case of an error.
Now I would like to catch this error in the process.
I tried to attach a boundaryEvent including an errorEventDefinition to the serviceTask as shown in the folowing example:

<serviceTask id="javaService" …/>
<boundaryEvent id="catchError" attachedToRef="javaService">
  <errorEventDefinition/>
</boundaryEvent>
<sequenceFlow id="errorFlow" sourceRef="catchError" targetRef="someOtherTask"/>

When running this the process I see the exception on the Tomcat console, but it is neither caught by the process nor is the process continued with someOtherTask.

What am I doing wrong?
Is it possible to catch Java Exceptions inside the process?
4 REPLIES 4

jbarrez
Star Contributor
Star Contributor
Error events are used for 'business' exceptions.

Java exceptions need to be handled in a different way, from the userguide;

When custom logic is executed, it is often required to catch certain exceptions. One common use case is to route process execution through another path in case some exception occurs. The following example shows how this is done.

<serviceTask id="javaService"
  name="Java service invocation"
  activiti:class="org.activiti.ThrowsExceptionBehavior">           
</serviceTask>
   
<sequenceFlow id="no-exception" sourceRef="javaService" targetRef="theEnd" />
<sequenceFlow id="exception" sourceRef="javaService" targetRef="fixException" />

Here, the service task has two outgoing sequence flow, called exception and no-exception. This sequence flow id will be used to direct process flow in case of an exception:

public class ThrowsExceptionBehavior implements ActivityBehavior {

  public void execute(ActivityExecution execution) throws Exception {
    String var = (String) execution.getVariable("var");

    PvmTransition transition = null;
    try {
      executeLogic(var);
      transition = execution.getActivity().findOutgoingTransition("no-exception");
    } catch (Exception e) {
      transition = execution.getActivity().findOutgoingTransition("exception");
    }
    execution.take(transition);
  }
 
}

kaech
Champ in-the-making
Champ in-the-making
Thank you. I somehow missed that in the user guide.

Using the suggested approach, part of the process flow would be hidden in Java code.
From a modeling perspective that's a bit weird, isn't it?

Wouldn't it be better to catch the exception in the process as shown in my example above?

jbarrez
Star Contributor
Star Contributor
We've discussed this internally when we implemented the error boundary event, and we came to the conclusion that the error event is meant for errors with a 'process' meaning. A Java exception is something that always will be implemented by a developer, so that stuff needs to be hidden from the common model between devs and analysts. However if you want the semantics you write, you could catch your exception and call the ErrorEndEventActivityBehavior yourself.

kaech
Champ in-the-making
Champ in-the-making
I agree that the process modelers should not get in touch with Java exceptions implemented (thrown) by Java developers.
But from the developer side the situation is the same. The service developer should not care about the process in which the service is used. I think the process and the service should solely interact based on a contract.
Such a contract normally comprises in and out messages and exceptions. For Java this would be a Java interface.

If we implemented it in the way you suggested, it would mean that the service task requires knowledge about the process in which the service is used. Of course that is possible but process changes (e.g id changes) would require a change in the Java code. From a service design perspective that is far from being ideal.The Java code would rather become an itegral part of the process model limiting service reusability.

Possibly a better approach would be that the Java classes implementing the service tasks have to throw a certain Activiti exception instead of just Exception. This ServiceTaskException could have an errorId parameter to return an error code that can be handled by the process.

What do you think?