11 Using Service Error Recovery

This chapter contains the following topics:

11.1 Understanding Service Error Recovery

You use service error recovery functionality to store the errors that occur after a business function calls a business service. Service error recovery occurs after you call a business service and is used to handle the errors that the calling business function receives from this call. The errors can be from either the jdeCallBusinessService API error codes or from errors in the response (payload) XML.

When one of these types of errors occurs, the system saves data that was generated by the business service in the Services Error Recovery table (F0045). You can then use the Service Error Recovery program (P0045) to review the errors and reprocess the transactions that ended in error. Or you can use the Services Error Recovery batch program (R0045) to reprocess the transactions.

Note:

Service error recovery works only for business functions that use the jdeCallBusinessService API. Additionally, service error recovery can be used only if the returning payload contains a tag called <sz-errors>.

When the jdeCallBusinessService API call is successful, but an error occurs during the execution, the data that is saved in the F0045 is the content of the tag <sz-errors>, which is returned in the payload. This string is saved in the BSSVERR field in the F0045. The rest of the data associated with the transactions that end in error are known by the calling business function, which enables the user to reprocess the transaction using the P0045 or R0045 program.

These fields in the F0045 table are used to reprocess the transaction:

  • BSSVPCK - BSSV Package

  • SBFMDNM - BSSV Method Name

  • BSSVXML - Input XML for BSSV

  • BSSVTRTY - BSSV Transaction Type

Note:

The value object contains a field called szErrors that translates to the <sz-errors> XML tag when returned to the business function in the response XML. This is parsed out of the response XML to show the user the errors that are returned from the business service.

Before you can review service errors, or resend the data that was not successfully delivered by the business service, your business services must be coded to format the error strings that are returned to the business functions. The business function then processes and stores the service errors.

This diagram illustrates the process flow for service error recovery:

Figure 11-1 Process flow for service error recovery

Description of Figure 11-1 follows
Description of ''Figure 11-1 Process flow for service error recovery''

The following sections provide an overview of the two parts of the service error recovery flow:

  • Recognizing and storing service errors.

  • Reviewing errors and resending data.

11.1.1 Recognizing and Storing Service Errors

This section describes how the system recognizes errors and stores them when an error occurs while processing a business service. When you call a business service, it can fail for a number of reasons. The service error recovery flow differs based on the failure reason. The two different flows are based on these types of failure reasons:

  • A server connection issue or some other connection issue exists.

  • A failure occurs on the third-party end of the process.

In the event of a connection issue:

  1. An error status is returned from the business service to the business function.

  2. The business function hard-codes the error to 007:FIS.

    Note:

    The error 007:FIS is hard-coded for the Order Promising and Requisition Self Service business services, but might be different for other business services.
  3. The business function invokes the F0045 Log Service Errors business function (B0001250) to write data to the F0045.

In the event of a third-party error:

  1. The service receives errors from the third-party system or system errors.

  2. The service translates the error codes from the third-party system to JD Edwards EnterpriseOne error codes (DD alias).

  3. The service creates a string in the following format:

    "n1:alias1|n2:alias2|n3:alias3|...|nx:aliasx"

    • if nx = 0: error is at header level, system level, or the error is unique

    • nx<>0: transaction detail key where the error occurred

    • nx is DD GENKEY (40 characters)

    • Aliasx: error alias in E1 format

    • Aliasx is DD DTAI (10 characters)

  4. The service returns the error string to the calling function by means of the payload in the <sz-errors> tag.

  5. The calling function checks the error string.

    If the string is greater than 1,999 characters, the business function truncates the string to 1,999 characters. Some Oracle databases do not support more than two fields greater than 2KB in a table, and the XML BLOB field is already more than 2KB in the F0045 table. If the string is truncated, a truncation flag is set and sent to the error recovery business function.

  6. If the string is not null, the business function invokes the F0045 Log Service Errors business function (B0001250) to write data to the F0045 table.

    The error string is stored as is.

The flows differ in the way that they handle the error string. However, both flows use the F0045 Log Service Errors business function (B0001250) to write the error string to the F0045 table. The errors that occur while the system processes the call to jdeCallBusinessService are returned to the user and written to jdedebug.log.

Note:

The third party might send back multiple errors for one transaction if those errors occur on different detail records.

11.1.2 Reviewing Errors and Resending Data

After the business function processes the errors, you can review those errors using the Service Error Recovery program (P0045). The Service Error Recovery program:

  1. Displays the errors in a readable format.

    The system uses the Parse Service Error String (B0001270) and Service Error Cache (B0001280) business functions when the user reviews the errors.

  2. Unparses the error string, retrieves the error descriptions, and displays the details in a grid.

  3. If the truncation flag is set, the system displays a message indicating that the error list was truncated and that more details are available in the service logs.

  4. Enables you to cancel the transaction or resend the data associated with the transaction.

    The system uses the Consume Business Service business function (B0001260) to resend the xml message.

Additionally, you can use the Services Error Recovery batch program (R0045) to resend the data.

Note:

The error string returned from a service must conform to the format documented here; otherwise, the translation of the error details in the Service Error Recovery program might show unexpected results.

These business functions are used to review and reprocess service error information:

  • B0001260 – Consume Business Service

    This business function locks all records in the F0045 table that have the same key (BSSVPCK, SBFMDNM, GENKEY), fetches records for which the unique key identifier matches the identifier in the data structure and consumes the business service for the specified record.

  • B0001270 – Parse Service Error String

    This business function parses the BSSVERR error string, which is stored in the F0045 table, and saves records to cache. The function counts the number of error records in the BSSVERR string. It counts the number of pipes "|" and separates the fields when it finds a ":". If more than one record is found, it saves the records in a cache (B0001280). Otherwise, it returns the code and the key.

  • B0001280 – Service Error Cache

    This business function is a standard cache-managing business function.

11.1.3 Code Sample: Building the Error String and Mapping It to the Message

When you create your business service, you write code that builds the error string and maps it to the message. This business service code sample illustrates how to build the error string and map it to the message list:

 //Create error list to concatenate errors for return
        StringBuffer errorList = new StringBuffer();             

       //add message to list
                    if (errorList != null) {
                        errorList.append(DELIMITER + msgContext + ":" + 
                                         errorsVO.getF34A50_OWERROR());
                    }

         if (!errorList.toString().equals("")) {
            internalVO.setSzErrors(errorList.toString().substring(1));
        }

11.1.4 Code Sample: Invoking the F0045 Log Service Error Business Function (B0001250)

The code that invokes the B0001250 business function should be the same or similar for all business functions. This is an example of the C code:

/*============================================================
 * Call BSSV API
*============================================================*/
idReturnValue = jdeCallBusinessService(lpDSInternal->lpBhvrCom, 
                                 lpDSInternal->lpVoid,
 BSSV_PACKAGE,
 _J("processProcurement"), TRUE,
 szBSSVXMLString,
 &szBSSVPayloadReturn);

if( idReturnValue == CallBSSVNoError)
{
/*  Parse the XML String  */
xrcsStatus = XRCS_parseXMLStringRemoveEncoding(lpDSInternal->hParser, 
szBSSVPayloadReturn, &hPayloadDoc);
if(xrcsStatus != XRCS_SUCCESS) 
{
jdeTraceSz(NULL, _J("B34A1300 - XRCS_parseXMLStringRemoveEncoding 
failed.\n"));
idReturnValue = ER_ERROR;
}
else
{
/* Get Payload Root Element */
xrcsStatus = XRCS_getDocumentElement(hPayloadDoc,&hPayloadRootElm);
if(xrcsStatus != XRCS_SUCCESS) 
{
jdeTraceSz(NULL, _J("B34A1300 - XRCS_getDocumentElement failed for 
Payload element.\n"));
idReturnValue = ER_ERROR;
}
else
{
* Get Tag Element */
xrcsStatus = XRCS_getElementsByTagName(hPayloadRootElm, 
_J("sz-errors"), &hElm,&nElmCount);
   if(xrcsStatus != XRCS_SUCCESS) 
{
jdeTraceSz(NULL, _J("B34A1300 - XRCS_getElementsByTagName failed 
for szError tag.\n"));
idReturnValue = ER_ERROR;
}
else
{
/* Retrieve tag szErrors from bssvPayloadReturn into szBSSVError string */ 

if(nElmCount > 0 && hElm != (XRCS_hElement*) NULL)
{
XRCS_getElementText(hElm[0],&szXMLText);
jdeStrncpyTerminate((JCHAR *)szBSSVError, szXMLText,DIM 
(szBSSVError)) ;
idReturnValue = ER_ERROR;
if (jdeStrlen( szXMLText ) > MAX_ERR_LEN) 
{
dsD0001250A.cServiceErrorTruncationFlag = _J('1');  
}
bCallErrorRecovery = TRUE;
}
else
{
jdeTraceSz(NULL, _J("B34A1300 - Service consumed successfully.\
n"));
}}
}
}/* end else parse error */
} /* ed if no error in BSSV */
else
{
/* Error when connecting to BSSV - Assign "0:007FIS" to BSSVERR */
jdeStrncpyTerminate((JCHAR *)szBSSVError, (const JCHAR *)_J("0:007FIS"),
DIM (szBSSVError)) ;
bCallErrorRecovery = TRUE;
idReturnValue = ER_ERROR;
}

if ( bCallErrorRecovery )
{
/* Call B0001250 */
dsD0001250A.idBSSVDocHandle = (ID)jdeStoreDataPtr(lpDSInternal->hUser, 
lpDSInternal->hDoc);
dsD0001250A.cSuppressErrorMessage = _J('1');
jdeStrncpyTerminate(dsD0001250A.szBSSVPackage,  
BSSV_PACKAGE,
DIM(dsD0001250A.szBSSVPackage));
jdeStrncpyTerminate(dsD0001250A.szBSSVMethodName,  
(const JCHAR *)_J("processProcurement"),
DIM(dsD0001250A.szBSSVMethodName));             
jdeStrncpyTerminate((JCHAR *)szPipe, (const JCHAR *)_J("|"),DIM (szPipe));
FormatMathNumeric(szOrderNumber, &lpdsD4302470A->mnOrderNumber) ;
jdeStrcat(szOrderNumber, szPipe);
jdeStrcat(szOrderNumber, lpdsD4302470A->szOrderType);
jdeStrcat(szOrderNumber, szPipe);
jdeStrcat(szOrderNumber, lpdsD4302470A->szOrderCompany);
jdeStrcat(szOrderNumber, szPipe);
jdeStrcat(szOrderNumber, lpdsD4302470A->szOrderSuffix);
jdeStrncpyTerminate((JCHAR *)dsD0001250A.szTransactionKey, 
szOrderNumber,DIM (dsD0001250A.szTransactionKey)) ;   
dsD0001250A.cActionCode = lpdsD4302470A->cOrderAction;
jdeStrncpyTerminate((JCHAR *)dsD0001250A.szBSSVTransactionType, 
(const JCHAR *)_J("AUTO"),DIM (dsD0001250A.szBSSVTransactionType)) ;   
jdeStrncpyTerminate((JCHAR *)dsD0001250A.szBSSVError, szBSSVError,DIM 
(dsD0001250A.szBSSVError)) ;   
jdeStrncpyTerminate((JCHAR *)dsD0001250A.szProgramId, 
(const JCHAR *)_J("B34A1300"),DIM (dsD0001250A.szProgramId)) ;   
jdeUTime_SetCurrentTime(&dsD0001250A.UniversalDateUpdated);
jdeStrncpyTerminate((JCHAR *)dsD0001250A.szCallingFunctionCode, 
lpDS->szCallingBusinessFunction, DIM (dsD0001250A.szCallingFunctionCode));

idReturnValue = jdeCallObject(_J("F0045LogServicesError"),
NULL, lpDSInternal->lpBhvrCom,
lpDSInternal->lpVoid,&dsD0001250A,
(CALLMAP*)NULL,(int)0,(JCHAR*)NULL,
(JCHAR*)NULL,(int)0);

if (idReturnValue == ER_ERROR)
{
jdeTraceSz(NULL, _J("B34A1300 - Error in call to B0001250: 
F0045LogServicesError.\n"));
}

} /* end if bCallErrorRecovery */
}

11.2 Managing Service Errors

This section provides an overview of service error management and discusses how to:

  • Set processing options for the Service Error Recovery programs (P0045 and R0045).

  • Review service errors and resend data.

  • Run the Services Error Recovery program (R0045).

11.2.1 Understanding Service Error Management

If you are using service error recovery functionality, you can use the Service Error Recovery program (P0045) to determine whether the data being sent by your business service was delivered successfully. If the data was not delivered, the system stores the data, along with an error message detailing the reason that the data was not delivered, in the Services Error Recovery table (F0045). The system recovers the errors for a service in sequential order, and each error record in the F0045 is identified by a unique key. Each F0045 record includes:

  • The method name, such as processProcurement.

  • The service XML.

  • The transaction type, which can be manual or auto.

  • Reprocess information, which the system uses to determine how many times the record has been reprocessed.

    The system uses this information so that the service can be consumed until it succeeds, or until a maximum reprocessing count is reached. When the maximum reprocessing count is reached, the system makes the record inactive.

Because different business transaction information and errors are stored, the transaction key is saved as generic text, in a concatenated format. For example, a procurement transaction key is stored as DOCO|DCTO|KCOO|SFXO. The action code for the transaction is also stored in the F0045. Action codes include:

  • 1: Add

  • 2: Change

  • 3: Delete

The description of the error, user-reserved fields, and audit information is also stored in the F0045 table.

You can review these error messages to determine whether issues with your system or process exist, or whether issues with the receiving system exist. You can also attempt to resend the data until the data is delivered successfully.

11.2.1.1 Resending Data

When you receive error messages, you can resend the data associated with the transaction, or you can delete the transaction. You can resend or delete transactions one at a time, or you can select multiple transactions at once. When you resend the data, the system locks the records that are related to the transactions being processed. You can also specify, using the processing options of the P0045 program, the number of times a record can be reprocessed before the record becomes inactive. If you reach the reprocessing count, and a record becomes inactive before it is sent successfully, you can reactivate the record and attempt to resend it.

Using the Services Error Recovery program (R0045), you can choose to resend all active and inactive records at one time. If you choose to resend inactive records, the system resets those records to active before processing them. Also, if you select a particular record for processing, the system reprocesses all of the records with the same package name in chronological order.

If reprocessing is successful, the record is deleted from the F0045 table, and the P0045 program no longer displays the error message. If the attempt to resend the data was not successful, the reprocess count is updated, and the record remains in the F0045 table.

11.2.1.2 Record Locking

When you attempt to reprocess records using either the P0045 or R0045 program, the system locks a set of records that are associated with the transaction being processed. The system locks all records with the same service package name (BSSVPCK), service method name (SBFMDNM), and transaction key (GENKEY) as the record being processed. The records are unlocked when processing is complete.

11.2.2 Forms Used to Manage Service Errors

Form Name FormID Navigation Usage
Work With Services Error W0045A Daily Operations menu (G34A/OP/ATO) Services Error Recovery Alternatively, Adv/Tech Operations menu (G43E31), PO Dispatch Error Recovery (P0045) Review service errors and resend data.
Service Error Recovery Revisions W0045C On the Work With Services Error form, select a record and click the View Errors button. View error details and update error records.

11.2.3 Setting Processing Options for the Service Error Recovery Programs (P0045 and R0045)

You use processing options to define default processing information for a program.

Note:

The R0045 and P0045 programs both use this set of processing options. However, the P0045 program uses only option 2 in this set of processing options.

11.2.3.1 Process

1. Records to Process:

Specify whether the R0045 program processes only active records from the F0045 table, or all active and inactive records. Active records have a value of A in the REPSTS field. Inactive records have a value of I in the REPSTS field. If you choose to reprocess all records, the system activates all inactive records and changes the reprocess count to 0 (zero) for those records. Values are:

Blank: Process only active records.

1: Process active and inactive records.

2. Reprocess Number:

Specify the maximum number of times that a service can be consumed and fail before the system sets the status to inactive. You must set this processing option to a value greater than zero when the Resend or Delete processing option is blank.

3. Resend or Delete:

Specify whether to resend or delete selected records when running the Service Error Recovery batch program (R0045). Values are:

Blank: Resend selected records.

1: Delete selected records.

11.2.4 Reviewing Service Errors and Resending Data

Access the Work With Services Error form.

BSSV Package (Business Service Package)

Enter the package name of the business service that is associated with the errors that you want to review. For example, to review errors that are generated by the PO Dispatch Processor business service (J43E0030), enter this package name and then click Find:

oracle.e1.bssv.J43E0030.PODispatchProcessor

Rep Num (Reprocess Number)

Review this field to determine how many times the system has attempted to resend the record to the supplier. If the value in this field is greater than the value that is set in the processing options for the allowed number of times to reprocess, the record becomes inactive and the system will not attempt to resend the record. You must manually reactivate the record to reprocess it.

Rep St (Reprocess Status)

Review the value in this field to determine whether the record is active. If the record is active, the system reprocesses the record. If the record is inactive and the R0045 is run, the system ignores the record and does not reprocess it unless you set the processing options of the R0045 program to process inactive records. Values include:

A or Blank: Active

I: Inactive

To resend the record to the external source, select the record, verify that it is active, and click the Resend button.

To review the details of the error associated with a particular record, select the record and then click the View Errors button.

Action Code

Review this field to determine the type of transaction that is in error. Values include:

1: Add a new record.

2: Change an existing record.

3: Delete an existing record.

4: Inquire on an existing record.

11.2.5 Running the Services Error Recovery Program (R0045)

Select Adv/Tech Operations menu (G43E31), PO Dispatch Error Recovery (R0045).

Note:

Two menu options are available with this name. One menu option enables you to access the P0045 program, and the other to access the R0045 program. Hover over the menu option with your mouse to view which program is associated with each menu option.