Error events are events which are triggered by a defined error.
Business Errors vs. Techincal Errors
A BPMN error is meant for business errors - which are different than technical exceptions. So, this is different than Java exceptions - which are, by default, handled in their own way.
Defining an Error
An error event definition references an error element. The following is an example of an error end event, referencing an error declaration:
<definitions> <error id="myError" errorCode="ERROR-OCCURED" name="ERROR-OCCURED"/> <!-- ... --> <process> <!-- ... --> <endEvent id="myErrorEndEvent"> <errorEventDefinition errorRef="myError" /> </endEvent> </process> </definitions>
You can trigger this error event either with a throwing error event within your process definition or from Delegation Code, see the Throwing BPMN Errors from Delegation Code section of the User Guide for more information.
Another possibility to define an error is setting of the type (class name) of any Java Exception as error code. Example:
<definitions> <error id="myException" errorCode="com.company.MyBusinessException" name="myBusinessException"/> ... <process> ... <endEvent id="myErrorEndEvent"> <errorEventDefinition errorRef="myException" /> </endEvent> </process> </definitions>
The exception type should only be used for business exceptions and not for technical exceptions in the process.
An error event handler references the same error element to declare that it catches the error.
Error Start Event
An error start event can only be used to trigger an Event Sub-Process - it cannot be used to start a process instance. The error start event is always interrupting.
Three optional attributes can be added to the error start event:
<definitions> <error id="myException" errorCode="com.company.MyBusinessException" name="myBusinessException"/> ... <process> ... <subProcess id="SubProcess_1" triggeredByEvent="true">> <startEvent id="myErrorStartEvent"> <errorEventDefinition errorRef="myException" camunda:errorCodeVariable="myErrorVariable" camunda:errorMessageVariable="myErrorMessageVariable" /> </startEvent> ... </subProcess> ... </process> </definitions>
errorRefis omitted, the subprocess will start for every error event that occurs.
camunda:errorCodeVariablewill contain the error code that was specified with the error.
camunda:errorMessageVariablewill contain the error message that was specified with the error.
camunda:errorMessageVariable can be retrieved like any other process variable, but only if the attribute was set.
Error End Event
When process execution arrives at an error end event, the current path of execution is ended and an error is thrown. This error can be caught by a matching intermediate error boundary event. In case no matching error boundary event is found, the execution semantics defaults to the none end event semantics.
|Attributes||camunda:asyncBefore, camunda:asyncAfter, camunda:errorCodeVariable, camunda:errorMessageVariable, camunda:exclusive, camunda:jobPriority|
Error Boundary Event
An intermediate catching error event on the boundary of an activity, or error boundary event for short, catches errors that are thrown within the scope of the activity on which it is defined.
Defining a error boundary event makes most sense on an embedded subprocess, or a call activity, as a subprocess creates a scope for all activities inside the subprocess. Errors are thrown by error end events. Such an error will propagate its parent scopes upwards until a scope is found on which a error boundary event is defined that matches the error event definition.
When an error event is caught, the activity on which the boundary event is defined is destroyed, also destroying all current executions therein (e.g., concurrent activities, nested subprocesses, etc.). Process execution continues following the outgoing sequence flow of the boundary event.
A error boundary event is defined as a typical boundary event. As with the other error events, the errorRef references an error defined outside of the process element:
<definitions> <error id="myError" errorCode="ERROR-OCCURED" name="name of error"/> <!-- ... --> <process> <!-- ... --> <subProcess id="mySubProcess"> <!-- ... --> </subProcess> <boundaryEvent id="catchError" attachedToRef="mySubProcess"> <errorEventDefinition errorRef="myError" camunda:errorCodeVariable="myErrorVariable" camunda:errorMessageVariable="myErrorMessageVariable" /> </boundaryEvent> </process> </definitions>
The errorCode is used to match the errors that are caught:
- If errorRef is omitted, the error boundary event will catch any error event, regardless of the errorCode of the error.
- In case an errorRef is provided and it references an existing error, the boundary event will only catch errors with the defined error code.
- If the errorCodeVariable is set, the error code can be retrieved using this variable.
- If the errorMessageVariable is set, the error message can be retrieved using this variable.
Unhandled BPMN Error
It can happens that no catching boundary event was defined for an error event. The default behaviour in this case is to log information and end the current execution.
This behaviour can be changed with
enableExceptionsAfterUnhandledBpmnError property set to
(via the process engine configuration or the deployment descriptor) and Process Engine Exception will be thrown if unhandled BPMN Error occurs.
Catch and Re-Throw Pattern
An error can be handled by the error start event in the event sub process and the same error can be thrown from the event sub process to handle the error on the higher level scope (in the example below, the error thrown from the Event Subprocess is handled by the error boundary event in the Subprocess).