Skip to content

Commit

Permalink
feat(simulator): support catch-all error and escalation events
Browse files Browse the repository at this point in the history
  • Loading branch information
sombrek authored and barmac committed Sep 25, 2024
1 parent 66f09cd commit b346a24
Show file tree
Hide file tree
Showing 23 changed files with 2,238 additions and 3 deletions.
17 changes: 15 additions & 2 deletions lib/simulator/Simulator.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import {
} from './util/SetUtil';

import {
eventsMatch
eventsMatch,
refsMatch
} from './util/EventsUtil';

import {
Expand Down Expand Up @@ -216,10 +217,22 @@ export default function Simulator(injector, eventBus, elementRegistry) {

const subscriptions = scope.subscriptions;

const matchingSubscriptions = filterSet(
let matchingSubscriptions = filterSet(
subscriptions, subscription => eventsMatch(event, subscription.event)
);

if (event.type === 'error' || event.type === 'escalation') {
const referenceSubscriptions = filterSet(
matchingSubscriptions, subscription => refsMatch(event, subscription.event)
);

if (matchingSubscriptions.every(subscription => subscription.event.boundary)
&& referenceSubscriptions.some(subscription => subscription.event.boundary)
|| referenceSubscriptions.some(subscription => !subscription.event.boundary)) {
matchingSubscriptions = referenceSubscriptions;
}
}

const nonInterrupting = matchingSubscriptions.filter(
subscription => !subscription.event.interrupting
);
Expand Down
10 changes: 9 additions & 1 deletion lib/simulator/util/EventsUtil.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
export function eventsMatch(a, b) {
return [ 'type', 'name', 'ref', 'iref' ].every(attr => !(attr in a) || a[attr] === b[attr]);
const attrMatch = [ 'type', 'name', 'iref' ].every(attr => !(attr in a) || a[attr] === b[attr]);
const catchAllMatch = !b.ref && (b.type === 'error' || b.type === 'escalation');

return attrMatch && (catchAllMatch || refsMatch(a, b));
}

export function refsMatch(a, b) {
const attr = 'ref';
return !(attr in a) || a[attr] === b[attr];
}
134 changes: 134 additions & 0 deletions test/spec/simulator/Simulator.error-catch-all-boundary-none.bpmn
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_0e0nrgo" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="5.26.0" modeler:executionPlatform="Camunda Cloud" modeler:executionPlatformVersion="8.5.0">
<bpmn:process id="Process_1" isExecutable="true">
<bpmn:startEvent id="StartEvent_1">
<bpmn:outgoing>Flow_1</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:subProcess id="SubProcess">
<bpmn:incoming>Flow_1</bpmn:incoming>
<bpmn:outgoing>Flow_4</bpmn:outgoing>
<bpmn:startEvent id="StartEvent_2">
<bpmn:outgoing>Flow_2</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:sequenceFlow id="Flow_2" sourceRef="StartEvent_2" targetRef="ErrorEndEvent_1" />
<bpmn:endEvent id="ErrorEndEvent_1" name="123">
<bpmn:incoming>Flow_2</bpmn:incoming>
<bpmn:errorEventDefinition id="ErrorEventDefinition_148z887" errorRef="Error_1pheg8y" />
</bpmn:endEvent>
</bpmn:subProcess>
<bpmn:sequenceFlow id="Flow_1" sourceRef="StartEvent_1" targetRef="SubProcess" />
<bpmn:endEvent id="EndEvent_2">
<bpmn:incoming>Flow_4</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_4" sourceRef="SubProcess" targetRef="EndEvent_2" />
<bpmn:endEvent id="EndEvent_7">
<bpmn:incoming>Flow_9</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_9" sourceRef="ErrorBoundary_none" targetRef="EndEvent_7" />
<bpmn:subProcess id="EventSubProcess_3" triggeredByEvent="true">
<bpmn:endEvent id="EndEvent_5">
<bpmn:incoming>Flow_7</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_7" sourceRef="OuterErrorStart_none" targetRef="EndEvent_5" />
<bpmn:startEvent id="OuterErrorStart_none" name="&#60;none&#62;">
<bpmn:outgoing>Flow_7</bpmn:outgoing>
<bpmn:errorEventDefinition id="ErrorEventDefinition_08h99id" />
</bpmn:startEvent>
</bpmn:subProcess>
<bpmn:subProcess id="EventSubProcess_4" triggeredByEvent="true">
<bpmn:endEvent id="EndEvent_6">
<bpmn:incoming>Flow_8</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_8" sourceRef="OuterErrorStart_123" targetRef="EndEvent_6" />
<bpmn:startEvent id="OuterErrorStart_123" name="123">
<bpmn:outgoing>Flow_8</bpmn:outgoing>
<bpmn:errorEventDefinition id="ErrorEventDefinition_0p01pld" errorRef="Error_1pheg8y" />
</bpmn:startEvent>
</bpmn:subProcess>
<bpmn:boundaryEvent id="ErrorBoundary_none" name="&#60;none&#62;" attachedToRef="SubProcess">
<bpmn:outgoing>Flow_9</bpmn:outgoing>
<bpmn:errorEventDefinition id="ErrorEventDefinition_1fabaar" />
</bpmn:boundaryEvent>
</bpmn:process>
<bpmn:error id="Error_1pheg8y" name="Error_123" errorCode="123" />
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
<dc:Bounds x="182" y="162" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_0nq6a1j_di" bpmnElement="SubProcess" isExpanded="true">
<dc:Bounds x="275" y="80" width="520" height="390" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_1r800jx_di" bpmnElement="StartEvent_2">
<dc:Bounds x="302" y="162" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_0avawzy_di" bpmnElement="ErrorEndEvent_1">
<dc:Bounds x="387" y="162" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="396" y="205" width="19" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_0o271ah_di" bpmnElement="Flow_2">
<di:waypoint x="338" y="180" />
<di:waypoint x="387" y="180" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="Event_0odig2x_di" bpmnElement="EndEvent_2">
<dc:Bounds x="852" y="162" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_1xrbbn8_di" bpmnElement="EndEvent_7">
<dc:Bounds x="482" y="532" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="BPMNShape_06xdd3c" bpmnElement="EventSubProcess_3" isExpanded="true">
<dc:Bounds x="850" y="280" width="190" height="120" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="BPMNShape_0u1gner" bpmnElement="EndEvent_5">
<dc:Bounds x="972" y="322" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_03mc40x_di" bpmnElement="OuterErrorStart_none">
<dc:Bounds x="880" y="322" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="879" y="365" width="38" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="BPMNEdge_075k5pd" bpmnElement="Flow_7">
<di:waypoint x="916" y="340" />
<di:waypoint x="972" y="340" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="BPMNShape_19s3z3r" bpmnElement="EventSubProcess_4" isExpanded="true">
<dc:Bounds x="1080" y="280" width="190" height="120" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="BPMNShape_1ubj6u9" bpmnElement="EndEvent_6">
<dc:Bounds x="1202" y="322" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_1km2n9z_di" bpmnElement="OuterErrorStart_123">
<dc:Bounds x="1110" y="322" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="1119" y="365" width="19" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="BPMNEdge_0770paz" bpmnElement="Flow_8">
<di:waypoint x="1146" y="340" />
<di:waypoint x="1202" y="340" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="Event_0mflkuu_di" bpmnElement="ErrorBoundary_none">
<dc:Bounds x="387" y="452" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="386" y="433" width="38" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_1an8gzo_di" bpmnElement="Flow_1">
<di:waypoint x="218" y="180" />
<di:waypoint x="275" y="180" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1ddz4nu_di" bpmnElement="Flow_4">
<di:waypoint x="795" y="180" />
<di:waypoint x="852" y="180" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1awq7qz_di" bpmnElement="Flow_9">
<di:waypoint x="405" y="488" />
<di:waypoint x="405" y="550" />
<di:waypoint x="482" y="550" />
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>
41 changes: 41 additions & 0 deletions test/spec/simulator/Simulator.error-catch-all-boundary-none.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
[
"createScope:Process_1:null",
"signal:Process_1:B",
"createScope:StartEvent_1:B",
"signal:StartEvent_1:C",
"exit:StartEvent_1:C",
"createScope:Flow_1:B",
"destroyScope:StartEvent_1:C",
"enter:Flow_1:B",
"exit:Flow_1:D",
"createScope:SubProcess:B",
"destroyScope:Flow_1:D",
"enter:SubProcess:B",
"createScope:StartEvent_2:E",
"signal:StartEvent_2:F",
"exit:StartEvent_2:F",
"createScope:Flow_2:E",
"destroyScope:StartEvent_2:F",
"enter:Flow_2:E",
"exit:Flow_2:G",
"createScope:ErrorEndEvent_1:E",
"destroyScope:Flow_2:G",
"enter:ErrorEndEvent_1:E",
"createScope:ErrorBoundary_none:B",
"signal:ErrorBoundary_none:I",
"destroyScope:ErrorEndEvent_1:H",
"exit:SubProcess:E",
"destroyScope:SubProcess:E",
"exit:ErrorBoundary_none:I",
"createScope:Flow_9:B",
"destroyScope:ErrorBoundary_none:I",
"enter:Flow_9:B",
"exit:Flow_9:J",
"createScope:EndEvent_7:B",
"destroyScope:Flow_9:J",
"enter:EndEvent_7:B",
"exit:EndEvent_7:K",
"destroyScope:EndEvent_7:K",
"exit:Process_1:B",
"destroyScope:Process_1:B"
]
156 changes: 156 additions & 0 deletions test/spec/simulator/Simulator.error-catch-all-boundary-ref.bpmn
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_0e0nrgo" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="5.26.0" modeler:executionPlatform="Camunda Cloud" modeler:executionPlatformVersion="8.5.0">
<bpmn:process id="Process_1" isExecutable="true">
<bpmn:startEvent id="StartEvent_1">
<bpmn:outgoing>Flow_1</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:subProcess id="SubProcess">
<bpmn:incoming>Flow_1</bpmn:incoming>
<bpmn:outgoing>Flow_4</bpmn:outgoing>
<bpmn:startEvent id="StartEvent_2">
<bpmn:outgoing>Flow_2</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:sequenceFlow id="Flow_2" sourceRef="StartEvent_2" targetRef="ErrorEndEvent_1" />
<bpmn:endEvent id="ErrorEndEvent_1" name="123">
<bpmn:incoming>Flow_2</bpmn:incoming>
<bpmn:errorEventDefinition id="ErrorEventDefinition_148z887" errorRef="Error_1pheg8y" />
</bpmn:endEvent>
</bpmn:subProcess>
<bpmn:sequenceFlow id="Flow_1" sourceRef="StartEvent_1" targetRef="SubProcess" />
<bpmn:endEvent id="EndEvent_2">
<bpmn:incoming>Flow_4</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_4" sourceRef="SubProcess" targetRef="EndEvent_2" />
<bpmn:endEvent id="EndEvent_7">
<bpmn:incoming>Flow_9</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_9" sourceRef="ErrorBoundary_none" targetRef="EndEvent_7" />
<bpmn:endEvent id="EndEvent_8">
<bpmn:incoming>Flow_10</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_10" sourceRef="ErrorBoundary_123" targetRef="EndEvent_8" />
<bpmn:subProcess id="EventSubProcess_3" triggeredByEvent="true">
<bpmn:endEvent id="EndEvent_5">
<bpmn:incoming>Flow_7</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_7" sourceRef="OuterErrorStart_none" targetRef="EndEvent_5" />
<bpmn:startEvent id="OuterErrorStart_none" name="&#60;none&#62;">
<bpmn:outgoing>Flow_7</bpmn:outgoing>
<bpmn:errorEventDefinition id="ErrorEventDefinition_08h99id" />
</bpmn:startEvent>
</bpmn:subProcess>
<bpmn:subProcess id="EventSubProcess_4" triggeredByEvent="true">
<bpmn:endEvent id="EndEvent_6">
<bpmn:incoming>Flow_8</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_8" sourceRef="OuterErrorStart_123" targetRef="EndEvent_6" />
<bpmn:startEvent id="OuterErrorStart_123" name="123">
<bpmn:outgoing>Flow_8</bpmn:outgoing>
<bpmn:errorEventDefinition id="ErrorEventDefinition_0p01pld" errorRef="Error_1pheg8y" />
</bpmn:startEvent>
</bpmn:subProcess>
<bpmn:boundaryEvent id="ErrorBoundary_none" name="&#60;none&#62;" attachedToRef="SubProcess">
<bpmn:outgoing>Flow_9</bpmn:outgoing>
<bpmn:errorEventDefinition id="ErrorEventDefinition_1fabaar" />
</bpmn:boundaryEvent>
<bpmn:boundaryEvent id="ErrorBoundary_123" name="123" attachedToRef="SubProcess">
<bpmn:outgoing>Flow_10</bpmn:outgoing>
<bpmn:errorEventDefinition id="ErrorEventDefinition_0a5sy6c" errorRef="Error_1pheg8y" />
</bpmn:boundaryEvent>
</bpmn:process>
<bpmn:error id="Error_1pheg8y" name="Error_123" errorCode="123" />
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
<dc:Bounds x="182" y="162" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_0nq6a1j_di" bpmnElement="SubProcess" isExpanded="true">
<dc:Bounds x="275" y="80" width="520" height="390" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_1r800jx_di" bpmnElement="StartEvent_2">
<dc:Bounds x="302" y="162" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_0avawzy_di" bpmnElement="ErrorEndEvent_1">
<dc:Bounds x="387" y="162" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="396" y="205" width="19" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_0o271ah_di" bpmnElement="Flow_2">
<di:waypoint x="338" y="180" />
<di:waypoint x="387" y="180" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="Event_0odig2x_di" bpmnElement="EndEvent_2">
<dc:Bounds x="852" y="162" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_1xrbbn8_di" bpmnElement="EndEvent_7">
<dc:Bounds x="482" y="532" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_0jdss59_di" bpmnElement="EndEvent_8">
<dc:Bounds x="712" y="532" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="BPMNShape_06xdd3c" bpmnElement="EventSubProcess_3" isExpanded="true">
<dc:Bounds x="850" y="280" width="190" height="120" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="BPMNShape_0u1gner" bpmnElement="EndEvent_5">
<dc:Bounds x="972" y="322" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_03mc40x_di" bpmnElement="OuterErrorStart_none">
<dc:Bounds x="880" y="322" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="879" y="365" width="38" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="BPMNEdge_075k5pd" bpmnElement="Flow_7">
<di:waypoint x="916" y="340" />
<di:waypoint x="972" y="340" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="BPMNShape_19s3z3r" bpmnElement="EventSubProcess_4" isExpanded="true">
<dc:Bounds x="1080" y="280" width="190" height="120" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="BPMNShape_1ubj6u9" bpmnElement="EndEvent_6">
<dc:Bounds x="1202" y="322" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_1km2n9z_di" bpmnElement="OuterErrorStart_123">
<dc:Bounds x="1110" y="322" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="1119" y="365" width="19" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="BPMNEdge_0770paz" bpmnElement="Flow_8">
<di:waypoint x="1146" y="340" />
<di:waypoint x="1202" y="340" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="Event_1hwhjpy_di" bpmnElement="ErrorBoundary_123">
<dc:Bounds x="617" y="452" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="625" y="433" width="19" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_0mflkuu_di" bpmnElement="ErrorBoundary_none">
<dc:Bounds x="387" y="452" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="386" y="433" width="38" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_1an8gzo_di" bpmnElement="Flow_1">
<di:waypoint x="218" y="180" />
<di:waypoint x="275" y="180" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1ddz4nu_di" bpmnElement="Flow_4">
<di:waypoint x="795" y="180" />
<di:waypoint x="852" y="180" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1awq7qz_di" bpmnElement="Flow_9">
<di:waypoint x="405" y="488" />
<di:waypoint x="405" y="550" />
<di:waypoint x="482" y="550" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0j7f3k4_di" bpmnElement="Flow_10">
<di:waypoint x="635" y="488" />
<di:waypoint x="635" y="550" />
<di:waypoint x="712" y="550" />
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>
Loading

0 comments on commit b346a24

Please sign in to comment.