Problem: When for any reasons a Container Managed service of type Web Service sets a return-code which is superior to the maximum success RETURN-CODE which indicates to Enterprise Server to Rollback, It can be interesting to retrieve to the client consuming the service a detailed information about what occurred. This is the aim of the MFRHSOAP User Exit 8. Resolution: I.) Introduction This sample demonstrates a simple COBOL user exit 8 program for MFRHSOAP, the Web Services request handler for Enterprise Server. MFRHSOAP user exits can be used to manipulate the SOAP request and response messages, the parameters passed to and from the COBOL service program, and other aspects of request processing. For more information, see the Net Express or Server Express 5 documentation. In the current documentation set, information on MFRHSOAP user exits can be found in Micro Focus Server → Configuration and Administration → Reference → User Exits. The sample user exit 8 allows you to update the content of the Soap Exception returned to the Web Service client II.) Contents The sample includes the following files: UserExit8.cbl legacy.cbl WSmanageSoapExceptionDetail-app.cbl WSmanageSoapExceptionDetail-proxy.cbl WSmanageSoapExceptionDetail-copy.cpy WShelloWorldSoapException.mpr WShelloWorldSoapException.app Source for the user exit 8 program. A simple web service to test the exit. The generated client application for legacy Additional generated sources for the client. Service mapping for the test service. Net Express 5 project file. III.) Building and Running the Sample Using Net Express 5 Websync3 and > If you have Net Express 5 Websync 3 or >, you should be able to build and run the sample using the enclosed project file: 1. 2. 3. 4. Start the target ES server. Open WShelloWorldSoapException.app in Net Express. Open the mapping file WShelloWorldSoapException.mpr in Net Express. See the service is of type container managed and it uses a maximum success RETURN-CODE of 5 to indicate success/failure 5. See the operation named LEGACY has one Input parameter of type int and one Output parameter of type int. The Input parameter is used to set a return-code 6. Set the service to use an exit handler for exit 8 ("End of Response Processing ") and exit 4 (“End of Input Request Processing”) In Net Express, this is configured using Operation → Properties... from the mapping window; In the service settings, set the name of the user exit program to " UserExit8". [ the Exit 4 is used to load the user Exit before the legacy code is invoked ] 7. Go to Service → Settings... and select your Enterprise Server. 8. Deploy the service For convenience, the UserExit8.int is deployed with the service. In a real life example, you would have to copy it to a directory listed in COBDIR on the system where your Enterprise Server is running.. 9. Generate the Web Service Client using Net Express menu Service->Generate Client using WSDL and select WSmanageSoapExceptionDetail.wsdl on sub-directory WShelloWorldSoapException\REPOS\WSmanageSoapExceptionDetail.deploy 10. Rebuild the project 11. Run the sample WSmanageSoapExceptionDetail-app. Supply an input numeric string when prompted. The LEGACY sample works this way: If your type as the input parameter an integer < 10 then the default SOAP exception is returned faultcode: Server faultstring: Error in Web Service application errordetail.errorcode: 6 errordetail.errortext: No more information available If your type as the input parameter an integer > 9 and < 21 then the service legacy code generates a RTS error and the following is returned faultcode: Server faultstring: Execution error in Web Service application errordetail.errorcode: 173 errordetail.errortext: Load error : file 'GenerRTS173' error code: 173, pc=1A9, call=1, seg=0 173 Called program file … If your type as the input parameter an integer > 20 and < 31 then the following SOAP exception is returned faultcode: Server ( APP-ERR ) faultstring: Custom: Error in Service application 25 errordetail.errorcode: 25 errordetail.errortext: Custom: Service has set RETURN-CODE to 25 which means... If your type as the input parameter an integer which is > 30 then the following SOAP exception is returned faultcode: Application ( APP-ERR ) faultstring: Custom: Error in Service application 35 errordetail.errorcode: 35 errordetail.errortext: Custom: (|) errortext 1 | errortext 2 (|) IV.) More glue on the implementation of the user exit 8 and its integration within the LEGACY code (legacy.cbl) 41) The SOAP envelope returned to Web Service client when an error occurs on Enterprise Server (ES) server side is: (errorcode = 35 is just an example here) ============== <SOAP-ENV:Body> <SOAP-ENV:Fault> <faultcode>Server</faultcode> <faultstring>Error in Web Service application</faultstring> <detail> <e:errordetail xmlns:e="http://xml.microfocus.com/cobol/mapperfault"> <errorcode>35</errorcode> <errortext>No more information available</errortext> </e:errordetail> </detail> </SOAP-ENV:Fault> </SOAP-ENV:Body> </SOAP-ENV:Envelope> ============== 42) See in the XML node <SOAP-ENV:Fault> we would like to customize the elements faultcode & faultstring & errortext (errorcode is set by the legacy code mapped as a service) 43) See the LEGACY Code, legacy.cbl uses in its working-storage a COPY file named custom-SOAPException.cpy (COPY file below used commonly by Service LEGACY code and user-exit 8) (copy custom-SOAPException. *> Declaration of an external variable named custom-SOAPException 78 faultcodeLength value 15. 78 faultErrorLength value 256. 01 custom-SOAPException is external. 02 custom-faultCode pic x(faultcodeLength). 88 custom-faultCodeServer value "Server". 88 custom-faultCodeAppl value "Application". 02 custom-faultstring pic x(faultErrorLength). 02 custom-errortext pic x(faultErrorLength). 44) See, in the legacy code you just have to MOVE content to custom-faultCode & customfaultstring & custom-errortext So these values are retrieved to the Web Service client … linkage section. 01 LS-rtncode cblt-rtncode. procedure division using LS-rtncode. … *> BEGIN CALLED mode if LS-rtncode > MAX-SUCCESS-RETURN-CODE initialize custom-SOAPException move LS-rtncode to WS-rtncodeD EVALUATE LS-rtncode when < 10 continue *> return default when > 9 and < 21 call "GenerRTS173" *> generate a RTS error, 173 here when > 20 and < 31 set custom-faultCodeServer to TRUE string "Custom: " "Error in Service application " WS-rtncodeD into custom-faultstring string "Custom: " " Service has set RETURN-CODE to " WS-rtncodeD " which means ..." into custom-errortext when other set custom-faultCodeAppl to TRUE string "Custom: " "Error in Service application " WS-rtncodeD into custom-faultstring string "Custom: " " <|> " "errortext 1" "|" "errortext 2" " <|> " into custom-errortext end-evaluate end-if exit program returning LS-rtncode stop run returning LS-rtncode. *> END CALLED mode 45) Previous step means you don’t have really to know how the User Exit 8 was implemented In the current documentation set, information on MFRHSOAP user exits can be found in Micro Focus Server → Configuration and Administration → Reference → User Exits. V.) .ZIP attached contains a Dot Net solution too This solution contains a WPF COBOL project & a WPF C# project & a VB WPF project, The aim of these projects being to consume the WS detailed above And handle the SOAP Exception Retrieve the Detail of this SOAP exception (customized) As in the screenshot below: