錯(cuò)誤事件(Error Events):
- 錯(cuò)誤事件是一個(gè)被定義好的錯(cuò)誤觸發(fā)的事件
業(yè)務(wù)錯(cuò)誤VS技術(shù)錯(cuò)誤(Business Errors vs. Technical Errors):
???? BPMN的錯(cuò)誤是業(yè)務(wù)錯(cuò)誤,這與技術(shù)錯(cuò)誤是不一樣的漂坏,所以它與Java的異常是不一樣的
一景埃、定義一個(gè)錯(cuò)誤(Defining an Error):
???? 錯(cuò)誤事件定義會(huì)引用一個(gè)error元素,下面就是一個(gè)error end事件的例子顶别,引用了一個(gè)error申明:
<definitions>
<error id="myError" errorCode="ERROR-OCCURED" name="ERROR-OCCURED"/>
<!-- ... -->
<process>
<!-- ... -->
<endEvent id="myErrorEndEvent">
<errorEventDefinition errorRef="myError" />
</endEvent>
</process>
</definitions>
???? 你可以通過拋出一個(gè)在流程中定義的錯(cuò)誤事件來觸發(fā)這個(gè)錯(cuò)誤事件谷徙,或者通過委派給代碼實(shí)現(xiàn),詳情見用戶指南
???? 另一種定義錯(cuò)誤的方式是設(shè)置Java異常的類名驯绎,如下例:
<definitions>
<error id="myException" errorCode="com.company.MyBusinessException" name="myBusinessException"/>
<!-- ... -->
<process>
<!-- ... -->
<endEvent id="myErrorEndEvent">
<errorEventDefinition errorRef="myException" />
</endEvent>
</process>
</definitions>
- 這個(gè)異常應(yīng)該只被用作業(yè)務(wù)異常完慧,而不應(yīng)該被用作技術(shù)異常
- 錯(cuò)誤事件handler引用了相同的錯(cuò)誤元素,以表明它是來捕獲處理這個(gè)錯(cuò)誤的
???? 錯(cuò)誤事件也可以通過camunda:errorMessage屬性定義一個(gè)錯(cuò)誤消息剩失,來擴(kuò)展錯(cuò)誤元素屈尼,以提供有關(guān)錯(cuò)誤的進(jìn)一步信息。這個(gè)引用錯(cuò)誤事件的定義必須指明camunda:errorMessageVariable去接收錯(cuò)誤消息拴孤,這個(gè)錯(cuò)誤消息也可以包含表達(dá)式脾歧。
<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>
???? 當(dāng)錯(cuò)誤事件拋出的錯(cuò)誤被捕獲到,會(huì)創(chuàng)建一個(gè)名叫err的流程變量(process variable)演熟,用以保存解析出來的消息鞭执。
二、錯(cuò)誤開始事件(Error Start Event):
- 錯(cuò)誤開始事件只能被用作觸發(fā)一個(gè)事件子流程绽媒,它不能被用作發(fā)起一個(gè)流程實(shí)例蚕冬,錯(cuò)誤開始事件是可中斷的
???? 錯(cuò)誤開始事件有三個(gè)可選屬性: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>
1.如果errorRef屬性被省略掉是辕,那么任何一個(gè)錯(cuò)誤事件發(fā)生,都會(huì)導(dǎo)致一個(gè)錯(cuò)誤子流程被發(fā)起
2.camunda:errorCodeVariable可以包含一個(gè)由錯(cuò)誤指定的錯(cuò)誤碼
3.camunda:errorMessageVariable可以包含一個(gè)由錯(cuò)誤指定的錯(cuò)誤消息
???? 如果流程中設(shè)置了camunda:errorCodeVariable和camunda:errorMessageVariable屬性猎提,那么在流程中可以像獲取其他變量一樣獲取這兩個(gè)屬性
三获三、錯(cuò)誤結(jié)束事件(Error End Event):
???? 當(dāng)流程執(zhí)行到錯(cuò)誤結(jié)束事件時(shí)蜻底,當(dāng)前路徑執(zhí)行結(jié)束侈询,并且向外拋出換一個(gè)錯(cuò)誤,這個(gè)錯(cuò)誤可以被匹配的中間錯(cuò)誤邊界事件(intermediate error boundary event)捕獲,如果沒有匹配的錯(cuò)誤邊界事件谦趣,這個(gè)執(zhí)行的語義跟默認(rèn)跟空結(jié)束事件的語義類似(啥也不干)
四、錯(cuò)誤邊界事件(Error Boundary Event):
???? 依附于一個(gè)活動(dòng)的邊界上的中間捕獲錯(cuò)誤事件或者簡(jiǎn)稱為錯(cuò)誤邊界事件铲汪,用于捕獲定義于這個(gè)活動(dòng)作用域內(nèi)的錯(cuò)誤叛溢。
???? 大多數(shù)場(chǎng)景下定義一個(gè)錯(cuò)誤邊界事件是為了包含一個(gè)子流程或者調(diào)用一個(gè)活動(dòng),作為一個(gè)子流程裸弦,會(huì)為所有包含在子流程內(nèi)的活動(dòng)創(chuàng)建一個(gè)作用域祟同。錯(cuò)誤會(huì)被錯(cuò)誤結(jié)束事件拋出,這個(gè)錯(cuò)誤會(huì)傳播到它的父作用域理疙,直到有一個(gè)匹配的錯(cuò)誤邊界事件晕城。
???? 當(dāng)錯(cuò)誤事件被捕獲,錯(cuò)誤邊界事件就會(huì)被銷毀窖贤,也會(huì)銷毀所有當(dāng)前包含在子流程里的活動(dòng)砖顷,流程會(huì)沿著錯(cuò)誤邊界事件所在的路徑進(jìn)行
???? 錯(cuò)誤邊界事件時(shí)一個(gè)典型的邊界事件,和其他錯(cuò)誤事件一樣赃梧,errorRef引用一個(gè)定義在process元素之外的error
<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被用作匹配其他被捕獲到的錯(cuò)誤:
???? 1.如果errorRef被忽略掉滤蝠,錯(cuò)誤邊界事件會(huì)捕獲所有的錯(cuò)誤事件,不管是什么錯(cuò)誤的errorCode
???? 2.如果errorRef有授嘀,并且它引用一個(gè)存在的錯(cuò)誤物咳,邊界事件將只會(huì)捕獲定義過error code的錯(cuò)誤
???? 3.如果errorCodeVariable被設(shè)置過,error code可以被提取出來用作變量
???? 4.如果errorMessageVariable被設(shè)置粤攒,error message可以被提取出來用作變量
五所森、沒有處理的BPMN錯(cuò)誤(Unhandled BPMN Error):
???? 如果發(fā)生的錯(cuò)誤事件沒有被定義錯(cuò)誤邊界事件,在這種情況下夯接,默認(rèn)行為是打印log日志并結(jié)束當(dāng)前任務(wù)焕济,這個(gè)行為可以通過設(shè)置enableExceptionsAfterUnhandledBpmnError屬性為true來改變,如果沒有處理的BPMN錯(cuò)誤發(fā)生盔几,一個(gè)流程引擎錯(cuò)誤將會(huì)被拋出