Unable to produce INTERNALLY_TERMINATED status

Like this?

Now i added a task which simply adds a “my_error_var”. Now i certainly can use the REST-API to identify a failed process by searching for the variable name like this: {{base_url}}/history/variable-instance?variableName=my_error_var.

But this approach seems to be rather cumbersome to me. If i have multiple process definitions i would have to make sure, that every one of them creates a variable with the same name.

Or maybe i misunderstood your approach?

My goal is create a generic Report on FAILED and COMPLETED processes without knowig their implementation details.

something like:


Error inbound event has error message variable
image

You can always use one name for all errors.

For failed instances, incidents will be created and you can query like below:

List<Incident> incidents = execution.getProcessEngineServices().getRuntimeService().createIncidentQuery()
				.processDefinitionKeyIn("processDefinitionKeys").incidentType("incidentType").orderByIncidentTimestamp()
				.asc().list();

For completed instances you can query for historic tables like below:

execution.getProcessEngineServices().getHistoryService().createHistoricProcessInstanceQuery()
				.processDefinitionKey("processDefinitionKey").completed();

@MaximMonin: Thanks for the clarification. Still i would need to make sure, that all process definitions on the server follow a certain pattern and always use the same variable name for errors. As i said my final goal is to create a generic Report on failed / completed processes without having to know their implementation details.

@aravindhrs: An incident seems to be a more convinient approach for my usecase. But the downside is, that incidents appearently are treated as technical errors. So how would i create an icident for buisiness type errors. In other words: How would my BPNM look like if there is a gateway flow which leads to an error/icident. The only way i can see at the moment is a custom service task like this:

@sreiser Incidents are for technical errors. If you want to filter the instances based on business error, then you should have model the process with error events which will have different status like “INTERNALLY_TERMINATED”, so while querying tasks you can filter by taskStatus.

For business errors,

throw new BpmnError(GOOD_UNAVAILABLE);

For technical errors,

execution.createIncident("incidentType", "configuration", "message");

https://docs.camunda.org/manual/7.14/reference/bpmn20/events/error-events/#business-errors-vs-technical-errors

This would be ideal for me, but the INTERNALLY_TERMINATED status unfortunatley only applies to sub-processes as @Yana described.

I debugged through some internal camunda code and found, that i can replace the default HistoryEventProducer. I customized the default HistoryEventProducer so that the status will always be set to INTERNALLY_TERMINATED if the last activity was an ErrorEndEvent.

So now the ErrorEndEvent will lead to the INTERNALLY_TERMINATED status regardless of whether it was on the parent or a sub-process. Any thoughts?

    @Configuration
    public class MyConfiguration {
        class MyHistoryEventProducer extends CacheAwareHistoryEventProducer {
            @Override
            protected void determineEndState(ExecutionEntity executionEntity, HistoricProcessInstanceEventEntity evt) {
                super.determineEndState(executionEntity, evt);
                ActivityImpl activity = executionEntity.getActivity();
                if (activity != null && activity.getActivityBehavior() instanceof ErrorEndEventActivityBehavior)
                    evt.setState(HistoricProcessInstance.STATE_INTERNALLY_TERMINATED);
            }
        }

        @Bean
        @Order(Ordering.DEFAULT_ORDER + 1)
        public ProcessEnginePlugin myConfig() {
            return new ProcessEnginePlugin() {
                @Override
                public void preInit(ProcessEngineConfigurationImpl processEngineConfiguration) {
                    processEngineConfiguration.setHistoryEventProducer(new MyHistoryEventProducer());
                }

                @Override
                public void postInit(ProcessEngineConfigurationImpl processEngineConfiguration) { }

                @Override
                public void postProcessEngineBuild(ProcessEngine processEngine) { }
            };
        }
    }