События ошибок (Error Events)
|
Этот раздел перенесён из документации Camunda 7 и в дальнейшем будет доработан с учётом особенностей OpenBPM Engine |
События ошибок — это события, которые срабатывают при возникновении определённой ошибки.
Бизнес-ошибки и технические ошибки
BPMN-ошибки предназначены для обработки бизнес-ошибок, которые отличаются от технических исключений. Таким образом, они не эквивалентны Java-исключениям, которые по умолчанию обрабатываются собственным механизмом.
Также рекомендуется предварительно ознакомиться с основами потоков выполнения и транзакций в Руководстве пользователя.
Определение ошибки
Определение события ошибки ссылается на элемент error. Ниже приведён пример конечного события ошибки, которое ссылается на объявление ошибки:
<definitions>
<error id="myError" errorCode="ERROR-OCCURED" name="ERROR-OCCURED"/>
<!-- ... -->
<process>
<!-- ... -->
<endEvent id="myErrorEndEvent">
<errorEventDefinition errorRef="myError" />
</endEvent>
</process>
</definitions>
Такое событие ошибки может быть инициировано либо выбрасывающим событием ошибки внутри процесса, либо из делегатного кода. Подробности см. в разделе Выбрасывание BPMN-ошибок из делегатного кода в Руководстве пользователя.
Другой способ определения ошибки — указание типа (имени класса) Java-исключения в качестве кода ошибки. Пример:
<definitions>
<error id="myException" errorCode="com.company.MyBusinessException"
name="myBusinessException"/>
<!-- ... -->
<process>
<!-- ... -->
<endEvent id="myErrorEndEvent">
<errorEventDefinition errorRef="myException" />
</endEvent>
</process>
</definitions>
Тип исключения следует использовать только для бизнес-исключений, но не для технических исключений в процессе.
Обработчик события ошибки ссылается на тот же элемент error, указывая, что он перехватывает соответствующую ошибку.
Также возможно определить сообщение об ошибке с помощью расширения
camunda:errorMessage
для элемента error, чтобы предоставить дополнительную информацию об ошибке.
Ссылающееся определение события ошибки должно указывать
camunda:errorMessageVariable,
чтобы получить это сообщение. Сообщение об ошибке может содержать
выражения.
<definitions>
<error id="myError" errorCode="ERROR-OCCURED" name="ERROR-OCCURED"
camunda:errorMessage="Something went wrong: ${errorCause}" />
<!-- ... -->
<process>
<!-- ... -->
<endEvent id="myErrorEndEvent">
<errorEventDefinition errorRef="myError" camunda:errorMessageVariable="err"/>
</endEvent>
</process>
</definitions>
Когда ошибка, выброшенная конечным событием ошибки, перехватывается, создаётся переменная процесса с именем err, содержащая вычисленное сообщение об ошибке.
Для External Tasks также возможно определять события ошибок с использованием
camunda:errorEventDefinition,
как показано в примере ниже. Дополнительно требуется выражение, которое должно вычислиться в true, чтобы BPMN-ошибка была выброшена.
Подробности см. в разделе
Руководство по External Tasks.
<serviceTask id="validateAddressTask"
name="Validate Address"
camunda:type="external"
camunda:topic="AddressValidation" >
<extensionElements>
<camunda:errorEventDefinition id="addressErrorDefinition"
errorRef="addressError"
expression="${externalTask.getErrorDetails().contains('address error found')}" />
</extensionElements>
</serviceTask>
Стартовое событие ошибки (Error Start Event)
Стартовое событие ошибки может использоваться только для запуска событийного подпроцесса (Event Sub-Process) — оно не может запускать экземпляр процесса напрямую. Стартовое событие ошибки всегда является прерывающим.
К стартовому событию ошибки могут быть добавлены три необязательных атрибута: errorRef, camunda:errorCodeVariable и camunda:errorMessageVariable:
<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>
-
Если
errorRefне указан, подпроцесс будет запускаться при возникновении любой ошибки. -
Переменная
camunda:errorCodeVariableбудет содержать код ошибки. -
Переменная
camunda:errorMessageVariableбудет содержать сообщение об ошибке.
Переменные camunda:errorCodeVariable и camunda:errorMessageVariable доступны как обычные переменные процесса, но только если соответствующие атрибуты были заданы.
Конечное событие ошибки (Error End Event)
Когда выполнение процесса достигает конечного события ошибки, текущий путь выполнения завершается и выбрасывается ошибка.
Эта ошибка может быть перехвачена соответствующим промежуточным граничным событием ошибки.
Если подходящее граничное событие ошибки не найдено, применяется семантика обычного конечного события (none end event).
Граничное событие ошибки (Error Boundary Event)
Промежуточное перехватывающее событие ошибки, размещённое на границе активности (граничное событие ошибки), перехватывает ошибки, выбрасываемые в пределах области видимости активности, к которой оно прикреплено.
Наиболее целесообразно определять граничные события ошибки на встроенных подпроцессах или call activity, поскольку подпроцесс создаёт область видимости для всех содержащихся в нём активностей. Ошибки выбрасываются конечными событиями ошибки и распространяются вверх по иерархии областей видимости до тех пор, пока не будет найдено совпадающее граничное событие ошибки.
При перехвате ошибки активность, к которой прикреплено граничное событие, уничтожается вместе со всеми текущими выполнениями внутри неё (например, параллельные активности, вложенные подпроцессы и т.д.). Выполнение процесса продолжается по исходящему потоку управления граничного события.
Граничное событие ошибки определяется как обычное граничное событие.
Как и для других событий ошибки, errorRef ссылается на ошибку, определённую вне элемента process:
<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>
Код ошибки (errorCode) используется для сопоставления перехватываемых ошибок:
-
Если
errorRefне указан, граничное событие ошибки перехватывает любые ошибки независимо от их кода. -
Если
errorRefуказан и ссылается на существующую ошибку, граничное событие перехватывает только ошибки с заданным кодом. -
Если задан
errorCodeVariable, код ошибки можно получить через соответствующую переменную. -
Если задан
errorMessageVariable, сообщение об ошибке можно получить через соответствующую переменную.
Неперехваченная BPMN-ошибка
Возможно, что для события ошибки не определено ни одного перехватывающего граничного события. Поведение по умолчанию в этом случае — запись информации в лог и завершение текущего выполнения.
Это поведение можно изменить, установив свойство enableExceptionsAfterUnhandledBpmnError в значение true
(через конфигурацию процессного движка или deployment descriptor).
В этом случае при возникновении неперехваченной BPMN-ошибки будет выброшено исключение Process Engine.
Шаблон «перехват и повторный выброс» (Catch and Re-Throw Pattern)
Ошибка может быть обработана стартовым событием ошибки в событийном подпроцессе, после чего та же ошибка может быть повторно выброшена из событийного подпроцесса для обработки на более высоком уровне области видимости (в приведённом ниже примере ошибка, выброшенная из Event Sub-Process, обрабатывается граничным событием ошибки в подпроцессе).
Лицензия и атрибуция
Эта документация была создана на базе материала "Camunda 7 Docs" от Camunda, находится под лицензией Creative Commons Attribution-ShareAlike 3.0 Unported License .
Оригинал документации: https://docs.camunda.org