bpmnServer / bpmn-server

BPMN 2.0 server for Node.js , providing modeling, execution, persistence and monitoring for Workflow. along with sample UI. Intended to be developers workbench for BPMN 2.0
MIT License
180 stars 46 forks source link

Exception handle #185

Closed kstan79 closed 5 months ago

kstan79 commented 6 months ago

Hi,

I'm try to implement exception in bpmn seems the intemediate event not fire. I think this feature is not implemented yet. I give camunda and kogito sample bpmn of handle exception. i dont know is it difficult to handle it or not.

[camunda] https://docs.camunda.org/manual/7.20/user-guide/process-engine/error-handling/

[kogito/jbpmn] https://blog.kie.org/2022/02/saga-pattern-with-processes-and-kogito-part-2.html

Base on observation, using try/catch while you navigate from 1 node to another node can help you branch out to error flow.

hope this info helpful.

kstan79 commented 6 months ago

in fact, i cant imagine how to determinte compensation boundaries & error boundaries in programming. according camunda statement seems

Compensation Boundaries = Cancel Error Boundaries = Programming error

Maybe (only suggestion:

  1. trigger Error Boundaries seems clear, can activate by throw exception a. receive exception will go error route (if exists) b. if undefine error handle, but there is error in program pass the default delegate error handle. (how bpmn deal with exception now?)

  2. trigger compensation boundaries below rules: a. set specific compensation properties at vars/data/option/instance (pick suitable place) to true:

    event.context.item.routeToCompensation(true)

    b. then bpmn identify is is this property set, if yes then it go different route c. if no define, then it throw error ask developer modify the code or modify the bpmn

As below image, we only need to throw error in "generate invoices", then it start "log errors" and end bpmn error

ralphhanna commented 6 months ago

There are several issues here:

  1. The intermediate event not firing, please submit your model for me to test
  2. bpmn error is for business errors not programming/environment errors
  3. bpmn error is supported by navigating to the event that raises the error and caught by another event image
  4. Escalation is similar to error
  5. Compensation only happens in the context of a Transaction
  6. Inside the transaction, compensation is raised by an Error or Cancel event
  7. Outside (after the transaction is complete), compensation can be raised by a Compensate event image
  8. Programming Error is handled by an Exception, should still save , but will do more testing next week

Thanks for bringing this issue forward

ralphhanna commented 6 months ago

Exceptions are handled fine, since we save every step of the workflow at start and at end. So the last item will look hanging of status: start or wait

kstan79 commented 6 months ago

hm... i think we use different approach cause that, i expect exception catch within the node, your way seems need additoinal gateway to catch it?

within try erro i have only below code

 console.log('Running listener  updateschedule.tryerror.start',);
    throw new InternalServerErrorException('purposely throw error')

i expect there is error event trigger to event listener, but it doesn't:

this.bpmnServer.listener.on(
      'all',
      async (event) => await this.applyEventListener(event),
    );
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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:camunda="http://camunda.org/schema/1.0/bpmn" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn">
  <bpmn:process id="errohandle" name="errors handler" isExecutable="false">
    <bpmn:startEvent id="StartEvent_1" name="update schedule">
      <bpmn:outgoing>Flow_1pg0fnn</bpmn:outgoing>
    </bpmn:startEvent>
    <bpmn:sequenceFlow id="Flow_1pg0fnn" sourceRef="StartEvent_1" targetRef="tryerror" />
    <bpmn:endEvent id="Event_1o6o4k2">
      <bpmn:incoming>Flow_170a071</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:sequenceFlow id="Flow_170a071" sourceRef="teacheracknowledge" targetRef="Event_1o6o4k2" />
    <bpmn:userTask id="teacheracknowledge" name="teacher acknowledge" camunda:assignee="kstan79">
      <bpmn:incoming>Flow_0i8h61u</bpmn:incoming>
      <bpmn:outgoing>Flow_170a071</bpmn:outgoing>
    </bpmn:userTask>
    <bpmn:sequenceFlow id="Flow_0i8h61u" sourceRef="tryerror" targetRef="teacheracknowledge" />
    <bpmn:serviceTask id="tryerror" name="try error">
      <bpmn:incoming>Flow_1pg0fnn</bpmn:incoming>
      <bpmn:outgoing>Flow_0i8h61u</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:boundaryEvent id="Event_1x43azn" attachedToRef="tryerror">
      <bpmn:outgoing>Flow_0ujgdj5</bpmn:outgoing>
      <bpmn:errorEventDefinition id="ErrorEventDefinition_1jljctq" />
    </bpmn:boundaryEvent>
    <bpmn:sequenceFlow id="Flow_0ujgdj5" sourceRef="Event_1x43azn" targetRef="errorhandler" />
    <bpmn:serviceTask id="errorhandler" name="error handler">
      <bpmn:incoming>Flow_0ujgdj5</bpmn:incoming>
      <bpmn:outgoing>Flow_0xn22s3</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:endEvent id="Event_1lr7684">
      <bpmn:incoming>Flow_0xn22s3</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:sequenceFlow id="Flow_0xn22s3" sourceRef="errorhandler" targetRef="Event_1lr7684" />
  </bpmn:process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="errohandle">
      <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
        <dc:Bounds x="122" y="102" width="36" height="36" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="100" y="145" width="81" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Event_1o6o4k2_di" bpmnElement="Event_1o6o4k2">
        <dc:Bounds x="562" y="102" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Activity_1vu7axv_di" bpmnElement="teacheracknowledge">
        <dc:Bounds x="400" y="80" width="100" height="80" />
        <bpmndi:BPMNLabel />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Activity_0vrmgin_di" bpmnElement="tryerror">
        <dc:Bounds x="200" y="80" width="100" height="80" />
        <bpmndi:BPMNLabel />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Activity_12q3140_di" bpmnElement="errorhandler">
        <dc:Bounds x="320" y="200" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Event_1lr7684_di" bpmnElement="Event_1lr7684">
        <dc:Bounds x="472" y="222" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Event_0nov24y_di" bpmnElement="Event_1x43azn">
        <dc:Bounds x="232" y="142" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="Flow_1pg0fnn_di" bpmnElement="Flow_1pg0fnn">
        <di:waypoint x="158" y="120" />
        <di:waypoint x="200" y="120" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_170a071_di" bpmnElement="Flow_170a071">
        <di:waypoint x="450" y="80" />
        <di:waypoint x="450" y="60" />
        <di:waypoint x="580" y="60" />
        <di:waypoint x="580" y="102" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_0i8h61u_di" bpmnElement="Flow_0i8h61u">
        <di:waypoint x="300" y="120" />
        <di:waypoint x="400" y="120" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_0ujgdj5_di" bpmnElement="Flow_0ujgdj5">
        <di:waypoint x="250" y="178" />
        <di:waypoint x="250" y="240" />
        <di:waypoint x="320" y="240" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_0xn22s3_di" bpmnElement="Flow_0xn22s3">
        <di:waypoint x="420" y="240" />
        <di:waypoint x="472" y="240" />
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</bpmn:definitions>
ralphhanna commented 6 months ago

I understand, will add in next release Thanks Sent from my iPhoneOn Mar 21, 2024, at 3:35 AM, Ks Tan @.***> wrote: hm... i think my problem is we use different way of implementation approach, i expect exception catch within the node, your way seems need additoinal gateway to catch it? <?xml version="1.0" encoding="UTF-8"?>

Flow_1pg0fnn Flow_170a071 Flow_0i8h61u Flow_170a071 Flow_1pg0fnn Flow_0i8h61u Flow_0ujgdj5 Flow_0ujgdj5 Flow_0xn22s3 Flow_0xn22s3 —Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you commented.Message ID: ***@***.***>
ralphhanna commented 5 months ago

please check latest release 2.1.11

ralphhanna commented 5 months ago

I am going to close this one