OnFault

Error handling in Stelring Integrator
Mirjana's picture

6. OnFault processing by 2 OnFaults (OnFault inside of OnFault)

 
Bpml Code:
 
<process name="default">
 <sequence name="mainChildSequence">
    <assign name="Assign" to="firstSequenceVar_1">1_1</assign>
    <operation name="File System Adapter">
      <participant name="FS_InstallValidation"/>
      <output message="FileSystemInputMessage">
        <assign to="." from="*"></assign>
        <assign to="Action">FS_COLLECT</assign>
        <assign to="filter">*.txt</assign>
        <assign to="deleteAfterCollect">false</assign>
      </output>
      <input message="inmsg">
        <assign to="." from="*"></assign>
      </input>
    </operation>
 
    <assign name="Assign" to="firstSequenceVar_2">1_2</assign>
 
<!--You can find a nested OnFault below -->
 
    <onFault>
      <sequence name="Sequence Start">
        <assign name="Assign" to="ERROR_ON_FAULT_1">Error processed by the FIRST OnFault</assign>
        <operation name="Business Process Exception">
          <participant name="BPExceptionService"/>
          <output message="BPExceptionServiceTypeInputMessage">
            <assign to="." from="*"></assign>
            <assign to="exceptionCode">34</assign>
          </output>
          <input message="inmsg">
            <assign to="." from="*"></assign>
          </input>
        </operation>
 
        <onFault>
          <sequence>
            <assign to="ERROR_ON_FAULT_1">Error processed by the SECOND OnFault</assign>
          </sequence>
        </onFault>
      </sequence>
    </onFault>
 </sequence>
</process>
 
BP flow:
 
We cannot see any step from any OnFault executed?!?!
 
 
Process Data:
 
There is no element in the Process Data that would be expected to be written from OnFault parts.
 
<?xml version="1.0" encoding="UTF-8"?>
<ProcessData>
 <firstSequenceVar_1>1_1</firstSequenceVar_1>
 <Prev_NotSuccess_Adv_Status>No files to collect</Prev_NotSuccess_Adv_Status>
 <ERROR_SERVICE>
    <WFD_NAME>TEST_onFault_in_OnFault</WFD_NAME>
    <SERVICE_NAME>FS_InstallValidation</SERVICE_NAME>
    <STEP_ID>2</STEP_ID>
    <ADV_STATUS>No files to collect</ADV_STATUS>
    <BASIC_STATUS>1</BASIC_STATUS>
    <WFC_ID>lin2:node1:12728cff242:6619171</WFC_ID>
 </ERROR_SERVICE>
</ProcessData>
 
Conclusion:
 
If we have OnFault in OnFault, seems that process will finish in Completed state, although any step from OnFault has not been executed at all. If we remove a 'child' OnFault, then it works as expected.
!!! Based on this result I would say that only one level of OnFault is permitted.
Mirjana's picture

5. OnFault processing in parent process (error from child process

Now, we will show 2 processes, a parent and child one:
 
Parent process:
 
 
<process name="default">
 <sequence name="mainParentSequence">
    <operation name="Invoke Business Process Service">
      <participant name="InvokeBusinessProcessService"/>
      <output message="InvokeBusinessProcessServiceTypeInputMessage">
        <assign to="." from="*"></assign>
        <assign to="INVOKE_MODE">SYNC</assign>
        <assign to="WFD_NAME">TEST_onFault_childProcess</assign>
        <assign to="NOTIFY_PARENT_ON_ERROR">NONE</assign>
      </output>
      <input message="inmsg">
        <assign to="." from="*"></assign>
      </input>
    </operation>
 
    <onFault>
      <sequence>
        <assign name="Assign" to="ERROR_PARENT">Error processed by the parent process</assign>
      </sequence>
    </onFault>
 </sequence>
</process>
 
 
Child process:
 
 
 
<process name="default">
 <sequence name="mainChildSequence">
    <assign name="Assign" to="firstSequenceVar_1">1_1</assign>
    <operation name="File System Adapter">
      <participant name="FS_InstallValidation"/>
      <output message="FileSystemInputMessage">
        <assign to="." from="*"></assign>
        <assign to="Action">FS_COLLECT</assign>
        <assign to="filter">*.txt</assign>
        <assign to="deleteAfterCollect">false</assign>
      </output>
      <input message="inmsg">
        <assign to="." from="*"></assign>
      </input>
    </operation>
 
    <assign name="Assign" to="firstSequenceVar_2">1_2</assign>
    <onFault code="No files to collect">
      <sequence name="Sequence Start">
        <assign name="Assign" to="ERROR_CHILD">Error processed by child process</assign>
      </sequence>
    </onFault>
    <onFault>
      <sequence name="Sequence Start">
        <operation name="Business Process Metadata">
          <participant name="BPMetaDataInfoService"/>
          <output message="BPMetaDataServiceTypeInputMessage">
            <assign to="." from="*"></assign>
            <assign to="TRACE">TRUE</assign>
          </output>
          <input message="inmsg">
            <assign to="." from="*"></assign>
          </input>
        </operation>
 
        <operation name="XSLT Service">
          <participant name="XSLTService"/>
          <output message="XSLTServiceTypeInputMessage">
            <assign to="." from="*"></assign>
            <assign to="xslt_name">TEST_error</assign>
            <assign to="xml_input_from">ProcData</assign>
            <assign to="input_pd_xpath">/</assign>
          </output>
          <input message="inmsg">
            <assign to="." from="*"></assign>
          </input>
        </operation>
 
        <operation name="Mail Mime Service">
          <participant name="MailMimeService"/>
          <output message="MailMimeServiceInputMessage">
            <assign to="." from="*"></assign>
            <assign to="mail-mime-subject">GIS error in sequence 1</assign>
            <assign to="mail-mime-sender">GIS_admin</assign>
            <assign to="mail-mime-operation">build</assign>
            <assign to="mail-mime-recipient">mirjana.vojvodic@tis.hr</assign>
          </output>
          <input message="inmsg">
            <assign to="." from="*"></assign>
          </input>
        </operation>
 
        <operation name="SMTP Send Adapter">
          <participant name="SMTP_SEND_ADAPTER"/>
          <output message="SMTP_SEND_ADAPTERInputMessage">
            <assign to="." from="*"></assign>
            <assign to="xport-smtp-mailto">mirjana.vojvodic@tis.hr</assign>
            <assign to="xport-smtp-mailhost">192.168.100.128</assign>
            <assign to="b2b-raw-message">true</assign>
            <assign to="xport-smtp-mailport">25</assign>
          </output>
          <input message="inmsg">
            <assign to="." from="*"></assign>
          </input>
        </operation>
 
      </sequence>
    </onFault>
 </sequence>
</process>
 
5.1         If there is OnFault in a child process, as well as in the parent process, then any error will be processed by a child process in the same way as it is shown in topics 2, 3 and 4
 
 
 
 
 
Process Data:
 
<?xml version="1.0" encoding="UTF-8"?>
<ProcessData>
 <firstSequenceVar_1>1_1</firstSequenceVar_1>
 <Prev_NotSuccess_Adv_Status>No files to collect</Prev_NotSuccess_Adv_Status>
 <ERROR_SERVICE>
    <WFD_NAME>TEST_onFault_childProcess</WFD_NAME>
    <SERVICE_NAME>FS_InstallValidation</SERVICE_NAME>
    <STEP_ID>2</STEP_ID>
    <ADV_STATUS>No files to collect</ADV_STATUS>
    <BASIC_STATUS>1</BASIC_STATUS>
    <WFC_ID>lin2:node1:12728cff242:5532968</WFC_ID>
 </ERROR_SERVICE>
 <ERROR_CHILD>Error processed by child process</ERROR_CHILD>
</ProcessData>
 
For any NOTIFY_PARENT_ON_ERROR mode, error will always be handled by a child process.
 
Process state:
 
Parent process will finish with green light and Completed state, and
Child process will finish with red light and also Completed state.
 
 
 
5.1.1 OnFault in a child process, but OnFault processing fails in a child process
 
 
 
 
Process Data:
 
<?xml version="1.0" encoding="UTF-8"?>
<ProcessData>
 <firstSequenceVar_1>1_1</firstSequenceVar_1>
 <Prev_NotSuccess_Adv_Status>34</Prev_NotSuccess_Adv_Status>
 <ERROR_SERVICE>
    <WFD_NAME>TEST_onFault_childProcess</WFD_NAME>
    <SERVICE_NAME>FS_InstallValidation</SERVICE_NAME>
    <STEP_ID>2</STEP_ID>
    <ADV_STATUS>No files to collect</ADV_STATUS>
    <BASIC_STATUS>1</BASIC_STATUS>
    <WFC_ID>lin2:node1:12728cff242:5577605</WFC_ID>
    <WFD_NAME>TEST_onFault_childProcess</WFD_NAME>
    <SERVICE_NAME>BPExceptionService</SERVICE_NAME>
    <STEP_ID>5</STEP_ID>
    <ADV_STATUS>34</ADV_STATUS>
    <BASIC_STATUS>1</BASIC_STATUS>
    <WFC_ID>lin2:node1:12728cff242:5577638</WFC_ID>
 </ERROR_SERVICE>
 <ERROR_CHILD>Error processed by a child process</ERROR_CHILD>
 <ERROR_PARENT>Error processed by the parent process</ERROR_PARENT>
</ProcessData>
 
Both processes finishes with red light but completed statuses, as an error in child process is handled by its own OnFault, but error that was thrown in child’s OnFault is handled by a parent’s OnFault:
 
 
 
5.2         OnFault omitted in a child process
 
If OnFault is omitted in a child process, any error can be handled by a parent process, but it depends on NOTIFY_PARENT_ON_ERROR parameter in Invoke BP Service.
 
5.2.1 NOTIFY_PARENT_ON_ERROR: Continue parent if any type error occurs in sub-process
 
Process flow:
 
  
 
 
Process Data:
 
<?xml version="1.0" encoding="UTF-8"?>
<ProcessData>
 <firstSequenceVar_1>1_1</firstSequenceVar_1>
 <Prev_NotSuccess_Adv_Status>No files to collect</Prev_NotSuccess_Adv_Status>
 <ERROR_SERVICE>
    <WFD_NAME>TEST_onFault_childProcess</WFD_NAME>
    <SERVICE_NAME>FS_InstallValidation</SERVICE_NAME>
    <STEP_ID>2</STEP_ID>
    <ADV_STATUS>No files to collect</ADV_STATUS>
    <BASIC_STATUS>1</BASIC_STATUS>
    <WFC_ID>lin2:node1:12728cff242:5591256</WFC_ID>
 </ERROR_SERVICE>
 <ERROR_PARENT>Error processed by the parent process</ERROR_PARENT>
</ProcessData>
 
Process state:
 
 
 
5.2.2 NOTIFY_PARENT_ON_ERROR: Halt sub-process if any error occurs (for potential correction and resume)
 
Process flow:
 
 
 
 
Process State:
 
 
Error is not handled in this case. Process is waiting for correction and resume!
 
 
Mirjana's picture

4. OnFault in a main as well as separated Sequences - processing error from OnFault

What will happen if we get an error in the OnFault part?
 
That can also happen. If we presume that mail is sent through OnFault processing, and mail server is not reachable in this moment, when we processing our OnFault part.
We can extend a previos process (from point 2), with one more sequence that we will name a mainSequence. In the case error happens in any of OnFaults, from firstSequence or secondSequence, then process will continue with OnFault connected to a main Sequence. If it fails as well, there is no way to finish process correctly, and it will stay in e.g. Halted state. You cannot be 100% sure that your process will always handle all possible errors.
 
 
 
Bpml code:
 
<process name="default">
 <sequence name="mainSequence">
    <sequence name="firstSequence">
      <assign name="Assign" to="firstSequenceVar_1">1_1</assign>
      <operation name="File System Adapter">
        <participant name="FS_InstallValidation"/>
        <output message="FileSystemInputMessage">
          <assign to="." from="*"></assign>
          <assign to="Action">FS_COLLECT</assign>
          <assign to="filter">*.txt</assign>
          <assign to="deleteAfterCollect">false</assign>
        </output>
        <input message="inmsg">
          <assign to="." from="*"></assign>
       </input>
      </operation>
 
      <assign name="Assign" to="firstSequenceVar_2">1_2</assign>
      <onFault code="No files to collect">
        <sequence name="Sequence Start">
          <assign name="Assign" to="ERROR_SEQ1">There is no files to collect from collection Folder!</assign>
        </sequence>
      </onFault>
      <onFault>
        <sequence name="Sequence Start">
          <operation name="Business Process Metadata">
            <participant name="BPMetaDataInfoService"/>
            <output message="BPMetaDataServiceTypeInputMessage">
              <assign to="." from="*"></assign>
              <assign to="TRACE">TRUE</assign>
            </output>
            <input message="inmsg">
              <assign to="." from="*"></assign>
            </input>
          </operation>
 
          <operation name="XSLT Service">
            <participant name="XSLTService"/>
            <output message="XSLTServiceTypeInputMessage">
              <assign to="." from="*"></assign>
              <assign to="xslt_name">TEST_error</assign>
              <assign to="xml_input_from">ProcData</assign>
              <assign to="input_pd_xpath">/</assign>
            </output>
            <input message="inmsg">
              <assign to="." from="*"></assign>
            </input>
          </operation>
 
          <operation name="Mail Mime Service">
            <participant name="MailMimeService"/>
            <output message="MailMimeServiceInputMessage">
              <assign to="." from="*"></assign>
              <assign to="mail-mime-subject">GIS error in sequence 1</assign>
              <assign to="mail-mime-sender">GIS_admin</assign>
              <assign to="mail-mime-operation">build</assign>
              <assign to="mail-mime-recipient">mirjana.vojvodic@tis.hr</assign>
            </output>
            <input message="inmsg">
              <assign to="." from="*"></assign>
            </input>
          </operation>
 
          <operation name="SMTP Send Adapter">
            <participant name="SMTP_SEND_ADAPTER"/>
            <output message="SMTP_SEND_ADAPTERInputMessage">
              <assign to="." from="*"></assign>
              <assign to="xport-smtp-mailto">mirjana.vojvodic@tis.hr</assign>
              <assign to="xport-smtp-mailhost">192.168.100.128</assign>
              <assign to="b2b-raw-message">true</assign>
              <assign to="xport-smtp-mailport">25</assign>
            </output>
            <input message="inmsg">
              <assign to="." from="*"></assign>
            </input>
          </operation>
 
        </sequence>
      </onFault>
    </sequence>
    <sequence name="secondSequence">
      <assign name="Assign" to="secondSequenceVar_1">2_1</assign>
      <operation name="XML Validation Service">
        <participant name="XMLValidator_WellFormed"/>
        <output message="XMLValidatorInputMessage">
          <assign to="." from="*"></assign>
        </output>
        <input message="inmsg">
          <assign to="." from="*"></assign>
        </input>
      </operation>
 
      <assign name="Assign" to="secondSequenceVar_2">2_2</assign>
      <onFault code="schema:validationerr">
        <sequence>
          <assign name="Assign" to="ERROR_SEQ2">XML validation error, Primary Document is not well-formed XML</assign>
          <operation name="Business Process Exception">
            <participant name="BPExceptionService"/>
            <output message="BPExceptionServiceTypeInputMessage">
              <assign to="." from="*"></assign>
              <assign to="exceptionCode">33</assign>
            </output>
            <input message="inmsg">
              <assign to="." from="*"></assign>
            </input>
          </operation>
 
        </sequence>
      </onFault>
      <onFault>
        <sequence name="Sequence Start">
          <operation name="Business Process Metadata">
            <participant name="BPMetaDataInfoService"/>
            <output message="BPMetaDataServiceTypeInputMessage">
              <assign to="." from="*"></assign>
              <assign to="TRACE">TRUE</assign>
            </output>
            <input message="inmsg">
              <assign to="." from="*"></assign>
            </input>
          </operation>
 
          <operation name="XSLT Service">
            <participant name="XSLTService"/>
            <output message="XSLTServiceTypeInputMessage">
              <assign to="." from="*"></assign>
              <assign to="xslt_name">TEST_error</assign>
              <assign to="xml_input_from">ProcData</assign>
              <assign to="input_pd_xpath">/</assign>
            </output>
            <input message="inmsg">
              <assign to="." from="*"></assign>
            </input>
          </operation>
 
          <operation name="Mail Mime Service">
            <participant name="MailMimeService"/>
            <output message="MailMimeServiceInputMessage">
              <assign to="." from="*"></assign>
              <assign to="mail-mime-subject">GIS error in sequence 2</assign>
              <assign to="mail-mime-sender">GIS_admin</assign>
              <assign to="mail-mime-operation">build</assign>
              <assign to="mail-mime-recipient">mirjana.vojvodic@tis.hr</assign>
            </output>
            <input message="inmsg">
              <assign to="." from="*"></assign>
           </input>
          </operation>
 
          <operation name="SMTP Send Adapter">
            <participant name="SMTP_SEND_ADAPTER"/>
            <output message="SMTP_SEND_ADAPTERInputMessage">
              <assign to="." from="*"></assign>
              <assign to="xport-smtp-mailto">mirjana.vojvodic@tis.hr</assign>
              <assign to="xport-smtp-mailhost">192.168.100.128</assign>
              <assign to="b2b-raw-message">true</assign>
              <assign to="xport-smtp-mailport">25</assign>
            </output>
            <input message="inmsg">
              <assign to="." from="*"></assign>
            </input>
          </operation>
 
        </sequence>
      </onFault>
    </sequence>
    <onFault>
      <sequence>
        <assign name="Assign" to="ERROR_MAIN">ERROR FROM A MAIN SEQUENCE</assign>
      </sequence>
    </onFault>
 </sequence>
</process>
 
If we force the error (33) in OnFault group in the second sequence, you can see that in the following part of code pasted above:
 
<onFault code="schema:validationerr">
        <sequence>
          <assign name="Assign" to="ERROR_SEQ2">XML validation error, Primary Document is not well-formed XML</assign>
          <operation name="Business Process Exception">
            <participant name="BPExceptionService"/>
            <output message="BPExceptionServiceTypeInputMessage">
              <assign to="." from="*"></assign>
              <assign to="exceptionCode">33</assign>
            </output>
            <input message="inmsg">
              <assign to="." from="*"></assign>
            </input>
          </operation>
 
        </sequence>
      </onFault>
 
... second sequence will fail with an error, its OnFault will also fail with an error, but the OnFault connected to the mainSequence can handle that error.
 
Process monitor, process flow:
 
 
 
We can see 3 errors, first from the firstSequence, another from the secondSequence and finally the 3rd that was thrown in OnFault of secondSequence, but it is all handled in the end, by OnFault group connected to a main sequence.
Assign element that is added in OnFault of main Sequence is:
 
<assign name="Assign" to="ERROR_MAIN">ERROR FROM A MAIN SEQUENCE</assign>
 
ProcessData from the end of the process is:
 
<?xml version="1.0" encoding="UTF-8"?>
<ProcessData>
 <firstSequenceVar_1>1_1</firstSequenceVar_1>
 <Prev_NotSuccess_Adv_Status>33</Prev_NotSuccess_Adv_Status>
 <ERROR_SERVICE>
    <WFD_NAME>TEST_onFault_handlingOnFaultError_inMainSequences</WFD_NAME>
    <SERVICE_NAME>FS_InstallValidation</SERVICE_NAME>
    <STEP_ID>2</STEP_ID>
    <ADV_STATUS>No files to collect</ADV_STATUS>
    <BASIC_STATUS>1</BASIC_STATUS>
    <WFC_ID>lin2:node1:12728cff242:5497625</WFC_ID>
    <WFD_NAME>TEST_onFault_handlingOnFaultError_inMainSequences</WFD_NAME>
   <SERVICE_NAME>XMLValidator_WellFormed</SERVICE_NAME>
    <STEP_ID>6</STEP_ID>
    <ADV_STATUS>schema:validationerr</ADV_STATUS>
    <BASIC_STATUS>1</BASIC_STATUS>
    <WFC_ID>lin2:node1:12728cff242:5497669</WFC_ID>
    <WFD_NAME>TEST_onFault_handlingOnFaultError_inMainSequences</WFD_NAME>
    <SERVICE_NAME>BPExceptionService</SERVICE_NAME>
    <STEP_ID>9</STEP_ID>
    <ADV_STATUS>33</ADV_STATUS>
    <BASIC_STATUS>1</BASIC_STATUS>
    <WFC_ID>lin2:node1:12728cff242:5497702</WFC_ID>
 </ERROR_SERVICE>
 <ERROR_SEQ1>There is no files to collect from collection Folder!</ERROR_SEQ1>
 <secondSequenceVar_1>2_1</secondSequenceVar_1>
 <XMLValidationError>
    <errorDetail>XML Validation: Failed to get primary document required for transaction to be completed.</errorDetail>
 </XMLValidationError>
 <ERROR_SEQ2>XML validation error, Primary Document is not well-formed XML</ERROR_SEQ2>
 <ERROR_MAIN>ERROR FROM A MAIN SEQUENCE</ERROR_MAIN>
</ProcessData>
 
Process state:
 
 
We can also see that process finished in Completed state:
 
Mirjana's picture

3. More than one sequence in a process

We separated a previous process into 2 sequences. Every sequence has its own OnFault group.
 
Example of the process is:
 
 
Bpml code:
 
<process name="default">
 <sequence>
    <sequence name="firstSequence">
      <assign to="firstSequenceVar_1">1_1</assign>
      <operation name="File System Adapter">
        <participant name="FS_InstallValidation"/>
        <output message="FileSystemInputMessage">
          <assign to="." from="*"></assign>
          <assign to="Action">FS_COLLECT</assign>
          <assign to="filter">*.txt</assign>
          <assign to="deleteAfterCollect">false</assign>
        </output>
        <input message="inmsg">
          <assign to="." from="*"></assign>
        </input>
      </operation>
 
      <assign to="firstSequenceVar_2">1_2</assign>
      <onFault code="No files to collect">
        <sequence name="Sequence Start">
          <assign name="Assign" to="ERROR_SEQ1">There is no files to collect from collection Folder!</assign>
        </sequence>
      </onFault>
      <onFault>
        <sequence name="Sequence Start">
          <operation name="Business Process Metadata">
            <participant name="BPMetaDataInfoService"/>
            <output message="BPMetaDataServiceTypeInputMessage">
              <assign to="." from="*"></assign>
              <assign to="TRACE">TRUE</assign>
            </output>
            <input message="inmsg">
              <assign to="." from="*"></assign>
            </input>
          </operation>
 
          <operation name="XSLT Service">
            <participant name="XSLTService"/>
            <output message="XSLTServiceTypeInputMessage">
              <assign to="." from="*"></assign>
              <assign to="xslt_name">TEST_error</assign>
              <assign to="xml_input_from">ProcData</assign>
              <assign to="input_pd_xpath">/</assign>
            </output>
            <input message="inmsg">
              <assign to="." from="*"></assign>
            </input>
          </operation>
 
          <operation name="Mail Mime Service">
            <participant name="MailMimeService"/>
            <output message="MailMimeServiceInputMessage">
              <assign to="." from="*"></assign>
              <assign to="mail-mime-subject">GIS error in sequence 1</assign>
              <assign to="mail-mime-sender">GIS_admin</assign>
              <assign to="mail-mime-operation">build</assign>
              <assign to="mail-mime-recipient">mirjana.vojvodic@tis.hr</assign>
            </output>
            <input message="inmsg">
              <assign to="." from="*"></assign>
            </input>
          </operation>
 
          <operation name="SMTP Send Adapter">
            <participant name="SMTP_SEND_ADAPTER"/>
            <output message="SMTP_SEND_ADAPTERInputMessage">
              <assign to="." from="*"></assign>
              <assign to="xport-smtp-mailto">mirjana.vojvodic@tis.hr</assign>
              <assign to="xport-smtp-mailhost">192.168.100.128</assign>
              <assign to="b2b-raw-message">true</assign>
              <assign to="xport-smtp-mailport">25</assign>
            </output>
            <input message="inmsg">
              <assign to="." from="*"></assign>
            </input>
          </operation>
 
        </sequence>
      </onFault>
    </sequence>
    <sequence name="secondSequence">
      <assign to="secondSequenceVar_1">2_1</assign>
      <operation name="XML Validation Service">
        <participant name="XMLValidator_WellFormed"/>
        <output message="XMLValidatorInputMessage">
          <assign to="." from="*"></assign>
        </output>
        <input message="inmsg">
          <assign to="." from="*"></assign>
        </input>
      </operation>
 
      <assign to="secondSequenceVar_2">2_2</assign>
      <onFault code="schema:validationerr">
        <sequence>
          <assign to="ERROR_SEQ2">XML validation error, Primary Document is not well-formed XML</assign>
        </sequence>
      </onFault>
      <onFault>
        <sequence name="Sequence Start">
          <operation name="Business Process Metadata">
            <participant name="BPMetaDataInfoService"/>
            <output message="BPMetaDataServiceTypeInputMessage">
              <assign to="." from="*"></assign>
              <assign to="TRACE">TRUE</assign>
            </output>
            <input message="inmsg">
              <assign to="." from="*"></assign>
            </input>
          </operation>
 
          <operation name="XSLT Service">
            <participant name="XSLTService"/>
            <output message="XSLTServiceTypeInputMessage">
              <assign to="." from="*"></assign>
              <assign to="xslt_name">TEST_error</assign>
              <assign to="xml_input_from">ProcData</assign>
              <assign to="input_pd_xpath">/</assign>
            </output>
            <input message="inmsg">
              <assign to="." from="*"></assign>
            </input>
          </operation>
 
          <operation name="Mail Mime Service">
            <participant name="MailMimeService"/>
            <output message="MailMimeServiceInputMessage">
              <assign to="." from="*"></assign>
              <assign to="mail-mime-subject">GIS error in sequence 2</assign>
              <assign to="mail-mime-sender">GIS_admin</assign>
              <assign to="mail-mime-operation">build</assign>
              <assign to="mail-mime-recipient">mirjana.vojvodic@tis.hr</assign>
            </output>
            <input message="inmsg">
              <assign to="." from="*"></assign>
            </input>
          </operation>
 
          <operation name="SMTP Send Adapter">
            <participant name="SMTP_SEND_ADAPTER"/>
            <output message="SMTP_SEND_ADAPTERInputMessage">
              <assign to="." from="*"></assign>
              <assign to="xport-smtp-mailto">mirjana.vojvodic@tis.hr</assign>
              <assign to="xport-smtp-mailhost">192.168.100.128</assign>
              <assign to="b2b-raw-message">true</assign>
              <assign to="xport-smtp-mailport">25</assign>
            </output>
            <input message="inmsg">
              <assign to="." from="*"></assign>
            </input>
          </operation>
 
        </sequence>
      </onFault>
    </sequence>
 </sequence>
</process>
 
OnFault group connected to the first sequence handles one specific error that is 'No files to collect' and a generic/default one.
OnFault group connected to the second sequence handles also one specific error i.e. 'schema:validationerr' and a generic/default one.
 
When filter in FSA is *.txt (that is a file that does not exists):
 
<assign to="filter">*.txt</assign>
 
... you can find that the the first (Assign) and the second (FSA) steps are executed from the first sequence, as error happened in teh FSA, BP continued with OnFault connected to that sequence. The second assign from that sequence has never been executed, but process continued with the second sequence. The second sequence also thrown an error and processed by its OnFault.
 
Process Monitor, BP flow:
 
 
 
Process Data in the end of the process is:
 
<?xml version="1.0" encoding="UTF-8"?>
<ProcessData>
 <firstSequenceVar_1>1_1</firstSequenceVar_1>
 <Prev_NotSuccess_Adv_Status>schema:validationerr</Prev_NotSuccess_Adv_Status>
 <ERROR_SERVICE>
    <WFD_NAME>TEST_onFault_twoSequences</WFD_NAME>
    <SERVICE_NAME>FS_InstallValidation</SERVICE_NAME>
    <STEP_ID>2</STEP_ID>
    <ADV_STATUS>No files to collect</ADV_STATUS>
    <BASIC_STATUS>1</BASIC_STATUS>
    <WFC_ID>lin2:node1:12728cff242:5451536</WFC_ID>
    <WFD_NAME>TEST_onFault_twoSequences</WFD_NAME>
    <SERVICE_NAME>XMLValidator_WellFormed</SERVICE_NAME>
    <STEP_ID>6</STEP_ID>
    <ADV_STATUS>schema:validationerr</ADV_STATUS>
    <BASIC_STATUS>1</BASIC_STATUS>
    <WFC_ID>lin2:node1:12728cff242:5451580</WFC_ID>
 </ERROR_SERVICE>
 <ERROR_SEQ1>There is no files to collect from collection Folder!</ERROR_SEQ1>
 <secondSequenceVar_1>2_1</secondSequenceVar_1>
 <XMLValidationError>
    <errorDetail>XML Validation: Failed to get primary document required for transaction to be completed.</errorDetail>
 </XMLValidationError>
 <ERROR_SEQ2>XML validation error, Primary Document is not well-formed XML</ERROR_SEQ2>
</ProcessData>
 
We can see that the second assign from both sequences (that would added values 1_2 and 2_2 into Process Data) were not run because every sequence stopped in the second step, i.e. FSA or XML Validation service and after that continued with OnFault.
 
Although steps from a sequnce will not be executed after a service that thrown an error, a new sequence in a BP will always be run, in spite of previous sequence that ended with an error.
 
If error happens in an OnFault group, then the whole process will stop and not continue with any new sequence. So condition to continue with the second sequence is that either the first sequence finish successfully or its OnFault processing part finish successfully.
Mirjana's picture

2. One sequence – handling two specific errors and one generic/default

In this process we have 2 services, FSA and XML Validation.
 
We will show 3 different cases, one when FSA throws the error 'No files to collect', another error thrown by the XMLValidation Service 'schema:validationerr' and finally generic error that is forced by BP Exception Service.
 
For handling specific errors, Error Value in Property Editor of OnFault group must be exactly Advanced Status returned by a service error.
In our cases we will handle 3 advanced statuses, as mentioned above. For BP Exception Service, Error Value is what has been defined in exceptionCode of BP Exception service. Errors/Exceptions that are handled in this BPs are:
 
  • No file to collect
  • schema:validationerr
  • 32
The last error 32 is not handled as a specific error, but through a generic part. Generic or any kind of error will be handled through Default OnFault part, that does not have any Error Value defined. Default error, without specific error value, always must be listed as the last one, because first specific errors will be handled and if any specific has been found in the list, then the error will be processed by process defined in a Default part.
If the Default part is placed in the first position, and specific errors after that, then any error will be processed by Default handling, and never go further to check if the specific error exists in the list.
 
Here is the example of the process:
 
 
Bpml code:
 
<process name="default">
 <sequence name="mainSequence">
    <operation name="File System Adapter">
      <participant name="FS_InstallValidation"/>
      <output message="FileSystemInputMessage">
        <assign to="." from="*"></assign>
        <assign to="filter">*.txt</assign>
 <assign to="deleteAfterCollect">false</assign>
      </output>
      <input message="inmsg">
        <assign to="." from="*"></assign>
      </input>
    </operation>
 
    <operation name="XML Validation Service">
      <participant name="XMLValidator_WellFormed"/>
      <output message="XMLValidatorInputMessage">
        <assign to="." from="*"></assign>
      </output>
      <input message="inmsg">
        <assign to="." from="*"></assign>
      </input>
    </operation>
 
    <operation name="Business Process Exception">
      <participant name="BPExceptionService"/>
      <output message="BPExceptionServiceTypeInputMessage">
        <assign to="." from="*"></assign>
        <assign to="exceptionCode">32</assign>
        <assign to="statusReport">my own error ...</assign>
      </output>
      <input message="inmsg">
        <assign to="." from="*"></assign>
      </input>
    </operation>
 
    <onFault code="No files to collect">
      <sequence name="Sequence Start">
        <assign name="Assign" to="ERROR">There is no files to collect from collection Folder!</assign>
      </sequence>
    </onFault>
    <onFault code="schema:validationerr">
      <sequence name="Sequence Start">
        <assign name="Assign" to="ERROR">XML validation error, Primary Document is not well-formed XML</assign>
      </sequence>
    </onFault>
    <onFault>
      <sequence name="Sequence Start">
        <operation name="Business Process Metadata">
          <participant name="BPMetaDataInfoService"/>
         <output message="BPMetaDataServiceTypeInputMessage">
            <assign to="." from="*"></assign>
            <assign to="TRACE">TRUE</assign>
          </output>
          <input message="inmsg">
            <assign to="." from="*"></assign>
          </input>
        </operation>
 
        <operation name="XSLT Service">
          <participant name="XSLTService"/>
          <output message="XSLTServiceTypeInputMessage">
            <assign to="." from="*"></assign>
            <assign to="xslt_name">TEST_error</assign>
            <assign to="xml_input_from">ProcData</assign>
            <assign to="input_pd_xpath">/</assign>
          </output>
          <input message="inmsg">
            <assign to="." from="*"></assign>
          </input>
        </operation>
 
        <operation name="Mail Mime Service">
          <participant name="MailMimeService"/>
          <output message="MailMimeServiceInputMessage">
            <assign to="." from="*"></assign>
            <assign to="mail-mime-subject">GIS error</assign>
            <assign to="mail-mime-sender">GIS_admin</assign>
            <assign to="mail-mime-operation">build</assign>
            <assign to="mail-mime-recipient">mirjana.vojvodic@tis.hr</assign>
          </output>
          <input message="inmsg">
            <assign to="." from="*"></assign>
          </input>
        </operation>
 
        <operation name="SMTP Send Adapter">
          <participant name="SMTP_SEND_ADAPTER"/>
          <output message="SMTP_SEND_ADAPTERInputMessage">
            <assign to="." from="*"></assign>
            <assign to="xport-smtp-mailto">mirjana.vojvodic@tis.hr</assign>
            <assign to="xport-smtp-mailhost">192.168.100.128</assign>
            <assign to="b2b-raw-message">true</assign>
            <assign to="xport-smtp-mailport">25</assign>
          </output>
          <input message="inmsg">
            <assign to="." from="*"></assign>
          </input>
        </operation>
 
      </sequence>
    </onFault>
 </sequence>
</process>
 
            To get the first error processed, No files to collect, you can set the filter in FSA to *.txt, as any txt file will not be found there
 
<assign to="filter">*.txt</assign>
 
Process monitor, process flow:
 
 
 
Process Data:
 
We can find the ERROR element in the Process Data that was created by Assign from OnFault.
 

<?xml version="1.0" encoding="UTF-8"?>

<ProcessData>
   <Prev_NotSuccess_Adv_Status>No files to collect</Prev_NotSuccess_Adv_Status>
  
<ERROR_SERVICE>
  
<WFD_NAME>TEST_onFault_oneSequence</WFD_NAME>
   <SERVICE_NAME>FS_InstallValidation</SERVICE_NAME>
   <STEP_ID>1</STEP_ID>
   
<ADV_STATUS>No files to collect</ADV_STATUS>
  
<BASIC_STATUS>1</BASIC_STATUS>
  
<WFC_ID>lin2:node1:12728cff242:5359512</WFC_ID>
  
</ERROR_SERVICE>
  
<ERROR>There is no files to collect from collection Folder!</ERROR>
</ProcessData>

State of the BP:

You can see that either BP has an error, it is in the Completed state, because Assign from OnFault finished successfully (3rd step in above picture):
 
 
 
            To get the second error processed, schema:validationerr, you can set the filter in FSA to *.vld, file will be found there, but not validated by XML Validation service
 
 <assign to="filter">*.vld</assign>
 
Process Monitor, process flow:
 
 
Process Data:
 
We can find the ERROR element in the Process Data that was created by Assign from OnFault:
 
<?xml version="1.0" encoding="UTF-8"?>
<ProcessData>
 <FileName>testdata.vld</FileName>
 <PrimaryDocument SCIObjectID="lin2:node1:12728cff242:5392528"/>
 <XMLValidationError>
    <errorDetail>Content is not allowed in prolog.</errorDetail>
 </XMLValidationError>
 <Prev_NotSuccess_Adv_Status>schema:validationerr</Prev_NotSuccess_Adv_Status>
 <ERROR_SERVICE>
    <WFD_NAME>TEST_onFault_oneSequence</WFD_NAME>
    <SERVICE_NAME>XMLValidator_WellFormed</SERVICE_NAME>
    <STEP_ID>2</STEP_ID>
    <ADV_STATUS>schema:validationerr</ADV_STATUS>
    <BASIC_STATUS>1</BASIC_STATUS>
    <WFC_ID>lin2:node1:12728cff242:5392534</WFC_ID>
 </ERROR_SERVICE>
 <ERROR>XML validation error, Primary Document is not well-formed XML</ERROR>
</ProcessData>
 
State of the BP:
 
This process is again in the Completed State as a previous one, because of proper OnFault handling:
 

  

 

 
            Handling a default error, that is like 'any error', we can force the process to pass both steps correctly (FSA and XML Validation) and force an error by BP Exception service
 
  • Create the file test.xml in /SI_install_dir/install/data/validation/collect.
  • Content of that file can the simpliest well-formed XML format as follows:
 
<root></root>
 
  • Change the filter in FSA into *.xml:
 
<assign to="filter">*.txt</assign>
 
 
Process Monitor, Process flow:
 
 
Advanced status returned by BP Exception Service, that is 32, has not been processed as a specific error, because it was not listed in OnFault error values, but it is then processed as a generic/default error. In Default error, we send a mail, that can be seen above.
 
XSLT used for that process is TEST_error.xslt:
 
<?xmlversion="1.0" encoding="iso-8859-2"?>
<xsl:stylesheetversion="1.0"xmlns:xsl="http://www.w3.org/1999/XSL/Transform"xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:output encoding="iso-8859-2" method="html"></xsl:output>
<xsl:template match="/">
 
Error appeared in a process!
         <br></br>
         <br></br>
Details about error:
<br></br>
<br></br>
<table border="1">
        
                   <tr>
                            <th align="left">BP name</th>
                            <td><xsl:value-of select="//ERROR_SERVICE/WFD_NAME/text()"></xsl:value-of></td>
                   </tr>
                   <tr>
                            <th align="left">BP ID</th>
                            <td><xsl:value-of select="//WORKFLOW_ID/text()"></xsl:value-of></td>
                   </tr>
                   <tr>
                            <th align="left">Service Name (error)</th>
                            <td><xsl:value-of select="//ERROR_SERVICE/SERVICE_NAME/text()"></xsl:value-of></td>
                   </tr>
                   <tr>
                            <th align="left">Step Id</th>
                            <td><xsl:value-of select="//ERROR_SERVICE/STEP_ID/text()"></xsl:value-of></td>
                   </tr>
                   <tr>
                            <th align="left">Advanced Status</th>
                            <td><xsl:value-of select="//ERROR_SERVICE/ADV_STATUS/text()"></xsl:value-of></td>
                   </tr>
                   </table>
 
<br></br>
         <br></br>
         To see more details about BP, go to SI administration:
         <br></br>
         <a><xsl:attribute name="href">http://192.168.101.144:16000/dashboard</xsl:attribute>http://192.168.101.144:16000/dashboard</a>
 
         <br></br>
         <br></br>
 
         GIS admin
 
</xsl:template>
</xsl:stylesheet>
 
 
The mail is:
 
 
 
Process state:
 
Again, we can see that process 130670 finished with Completed state:
 
  
 

 

Mirjana's picture

1. Few words about OnFault

OnFault is very important to be included in the BP. In the case of error in a business process, without proper OnFault handling, process can finish in Halted, Interrupted or another state. Processes in such states will never be archived from the system, that can cause performance issues.
If the error happens in the BP, but OnFault handles it properly, then we will find red light in the BP monitor that indicates error, but state of the process will be Completed, and such process will be archived.
There are 2 main reasons for OnFault handling:
 

  • one is notification about error or any kind of handling that is supposed to be done in the case of error
  • another reason is to finish the BP with Completed state so it can be archived and removed from a database properly. Only records that belong to business process that finished with Completed or Terminated statuses will be Indexed/archived/purged from a database. If OnFault is not used, and error happens in a BP, status will be Halted and never removed from a database.

 
OnFault is connected to a sequence (Sequence Start element), and in the case of any error on that sequence (between Sequence Start and Sequence End), process will be redirected into OnFault part, and ANY OTHER SERVICE/STEP from that sequence will NOT run after error has thrown. Sequence simply stops in the service that threw an error and continue with OnFault connected exactly to that sequence. 
 

Mirjana's picture

OnFault - error handling in Sterling Integrator BPs

Questions:
 
*******************************************************************
 
Q1) In a BP which has many sequences( some with its own Onfault ...some with no Onfault), if an error occurs in a sequence, which onfault would capture it...one or more than one?
 
A1) It is always an OnFault connected with a sequence in which error has happened.
 
*******************************************************************
 
Q2) How to instruct the process to go to a specific onFault upon encoutering a specific error.
 
A2) First topic in below explanation will answer this question
 
*******************************************************************
 
Q3) If an error occurs in a sequence( has its own Onfault) which is contained in another sequence,  is the error handled only by the Onfault of the sequence in which the error occured or is it handled by its own onfault as well as the onfault of the sequence that it is contained in(parent sequence)?
 
A3) Error is handled through an OnFault connected to a sequence, but if error happens in OnFault part, then that error will be handled by outermost sequence (if exists) and also by a parent process (if exists and if errors are propagated to a parent process). Explained in 4rd and 5th topic below.
 
*******************************************************************
 
Q4) What happens if there is an error in executing the code contained with in a Onfault ?   which Onfault would handle that error?
 
A4)
  • You can have a generic OnFault that will always work because you can simply put just an assign in it, as explained  in 4th topic.
  • OnFault inside of OnFault will not work and give an expected result (6th topic)
  • My opinion is not to force handling all the errors, e.g. if error happens in OnFault part. For example if we send a mail through OnFault, and mail server is down, then this process will finish in Halted state, but SI has a system BP, BPRecovery, that will find such processes in the system and try to Restart/Resume it every 10 minutes (depending on setting in the BP). Sometimes, it is good to have a BP in Halted state, for manual intervention as well, as sometimes problem has to be resolved by our manual intervention. It all depends on the process and expected errors, if they can be automatically resolved just by another restart or need a manual intervention.
 
*******************************************************************
 
Q5) If this BP is called from another BP, will the process exits after completing the execution of code in Onfault or is the control handed over back to the Parent process?
 
A5) Explained in 5th topic.
 
*******************************************************************
There are 6 topics that will explain different scenarios for error handling in Sterling Integrator …
 
Syndicate content