Error recovery

This page provides details on the general error recovery mechanism provided by the Desktop SDK.The easiest recovery procedure is available via QBFC, if you are using that QBFC automates most of what you need to do. However, in this chapter we’ll cover both QBFC and qbXML procedures.

The general error recovery mechanism

If your application adds, deletes, voids, or modifies data in the QuickBooks company file, you need to implement an error recovery routine. This routine enables your application to respond to and recover from conditions that interrupt normal processing of requests and responses. Examples of such error conditions include system crashes and power outages as well as internal system errors and out-of-memory conditions.

A simple error recovery routine asks QuickBooks to save its state, so that when a processing error occurs, you can ask QuickBooks to check its state and it can return status information to you about the request in question. For example, suppose your application sends a CheckAdd request to QuickBooks. The ProcessRequest method (or DoRequests method for QBFC) fails to return a response or result code. What should your application do? Does it assume the check was created? Does it assume the check wasn’t created? Either assumption, if incorrect, will cause problems. The correct approach is for your application to invoke an error recovery routine that checks the status of the CheckAdd request and determines whether processing succeeded or failed before it asks QuickBooks to add the check a second time.

If your application is a read-only application (that is, the only requests it sends are query requests), then you do not need to implement an error recovery routine.

When to invoke error recovery

When you receive an error from QuickBooks that indicates an error in processing a request, or when you do not receive a response from QuickBooks at all, your application needs to invoke its error recovery routine. In addition, if your application adds, deletes, modifies, or voids data in the QuickBooks company file, it should invoke its error recovery routine upon startup, in case the previous session terminated before all outstanding requests were successfully processed.

HRESULTs returned by QuickBooks

Applications integrating with QuickBooks should invoke their error recovery routine when any of the following error conditions occurs:

The General Error Recovery Mechanism403

Automated error recovery in QBFC

QBFC automates the SDK error-recovery mechanism described later in this chapter (see “Using Error Recovery in qbXML-based Applications”) by automatically managing the newMessageSetID and oldMessageSetID attributes and by saving the request message set to disk. This enables your application to determine which request corresponds to the response status that the error-recovery feature returns.

For QuickBooks,QBFC error-recovery information is unique to a given integrated application (via a GUID specified by ErrorRecoveryID) and company file. As a result, a session must be started before certain QBFC error-recovery functions can be executed. (Only EnableErrorRecovery, ErrorRecoveryID, and SaveAllMsgSetRequestInfo can be executed before a session is started.)

Note

Note

QBFC automated error recovery is available only for data message sets (not for subscription and event messages).

Implementing automated error recovery

In general, these are the steps you need to follow to use QBFC’s automated error recovery in your application:

  1. Set the error recovery ID, using the ErrorRecoveryID function.
  2. Set EnableErrorRecovery totrueto enable error recovery.
  3. Set SaveAllMsgSetRequestInfo totrueso the entire contents of the MsgSetRequest will be saved to disk. If Save All MsgSetRequestInfo isfalse(the default), only the newMessageSetID will be saved.
  4. Use IsErrorRecoveryInfo to check whether an unprocessed response exists. If IsErrorRecoveryInfo istrue:
    1. Get the response status, using GetErrorRecoveryStatus.
    2. Get the saved request, using GetSavedMsgSetRequest.
    3. Process the response, possibly using the saved request.
    4. Clear the response status, using ClearErrorRecovery.
  5. Send the current request set.
  6. Process the response from the current request.
  7. Clear the response status, using ClearErrorRecovery.

Error Recovery and Query Requests

Generally, error recovery is not used with query requests. If your application does not receive a response from a query request, you would usually just resubmit the query. We recommend that your application disable error recovery before querying, and then re-enable it before starting other requests.

Using error recovery in qbXML-based applications

If your application doesn’t use QBFC, you’ll have to do more work in implementing error recovery. You’ll need to know a few things that are simply done automatically and behind the scenes for QBFC.

Error recovery using old and new message IDs

The QuickBooks SDK error recovery mechanism employs two attributes: newMessageSetID and oldMessageSetID. Message set IDs need to be unique strings and are limited to 23 characters. (The colon, backward slash, and forward slash cannot be used in these IDs.) The newMessageSetID identifies the current message and enables the error recovery mechanism by signaling to QuickBooks that you want it to save the state of this message.

When you are sure QuickBooks has successfully processed a given message set, you send the message ID as the oldMessageSetID attribute, which has the effect of asking QuickBooks to clear that ID and associated data from its saved state.

Your application is responsible for generating the message set IDs, which must be unique within your application space. How you generate the value for the message ID is application-specific. For instance, you might use a language-dependent tool to generate the value. (The tool should ensure a unique value, not just a randomly generated one.)

How to clear all error recovery information

In some circumstances, you may need to delete all error recovery information that applies to your applications. To do this, simply set the oldMessageSetID value to ClearAllMessageSets. (oldMessageSetID = ClearAllMessageSets).

Steps for using error recovery in qbXML-based applications

The following steps outline a general procedure for implementing error recovery within your application. First, steps 1 through 6 describe what your application needs to do during normal, successful processing of a request.

  1. Create a unique newMessageSetID.
  2. Create the request message set, including the newMessageSetID attribute, and save the request message set in some persistent form. (Be sure to encrypt company file data or otherwise ensure that it is secure and not accessible from the file system.)
  3. Send the request message set.
  4. Receive the response and process it.
  5. If the response is successfully processed, delete the persistent copy of the request message set.
  6. Clear the oldMessageSetID (this is the “newMessageSetID” you used in Step 2).

If a crash or other processing error occurs, you will need to invoke your error recovery routine.

Here are the general steps:

  1. At startup, check for a saved request message set. (If the request message set is still save on disk—step 2, above—it was never cleared. This condition indicates some problem with normal processing outlined in steps 1 through 6.)

    If a saved request message set is present, resend the request set. This action has the effect of performing a status check for the message set. If QuickBooks has already processed all or some of the request, it will return the status for it. If QuickBooks has not already processed the request, it will process it and send a response.

  2. Based on the response from QuickBooks, you will need to fix the problem, if there is one. (If you just keep sending the same request without fixing problems, you’ll be in an endless loop.) After you’ve fixed or identified the problem, you need to generate a new newMessageSetID.

  3. Repeat steps 2 through 6, (sending the revised request with its new newMessageSetID to QuickBooks).

Example

The following example shows a CheckAdd request that includes a newMessageSetID. If an error in processing occurred and no response was received, the error recovery routine could send this same request again. If the request had been previously received, QuickBooks would interpret this second, identical request as a status check and would send back the response shown in the next example.

<QBXMLMsgsRq newMessageSetID = "DE9437D9-AA85-21E4-D643"
onError="continueOnError">
<CheckAddRq requestID = "1">
<CheckAdd>
<AccountRef>
<FullName>Checking</FullName>
</AccountRef>
<PayeeEntityRef>
<FullName>East Bayshore Auto Mall</FullName>
</PayeeEntityRef>
<TxnDate>2001-10-14</TxnDate>
<Memo>Installment check</Memo>
<ExpenseLineAdd>
<AccountRef>
<FullName>Automobile</FullName>
</AccountRef>
<Amount>520.00</Amount>
</ExpenseLineAdd>
</CheckAdd>
</CheckAddRq>
</QBXMLMsgsRq>

And the response to the preceding status check (the CheckAdd request with error recovery indicated by the newMessageSetID):

<?xml version="1.0" ?>
<QBXML>
<QBXMLMsgsRs newMessageSetID="DE9437D9-AA85-21E4-D643"
messageSetStatusCode="0">
<CheckAddRs requestID="1" statusCode="0" statusSeverity="Info" statusMessage="Status OK"/>
</QBXMLMsgsRs
</QBXML>
Message set status code

A messageSetStatusCode is returned to your application in response to an error recovery request, such as a status check or a clear status. It is also returned if some specific error recovery operation is invoked and fails, such as a standard check for a validmessage set ID; if the call fails, then a messageSetStatusCode is returned.

A messageSetStatusCode is not returned, for instance, if your application issues a check status request that returns successfully. It is good practice to test for this status code, regardless of the fact that in some cases it is not returned.

The following table shows the error recovery status codes and their meaning.

Code Meaning
0 Success
600 The oldMessageSetID does not match any stored IDs, and no newMessageSetID is provided.
9001

Invalid checksum. The newMessageSetID specified matches the

currently stored ID, but the checksum fails.

9002 No stored response was found.
9003 (Not used)
9004 InvalidMessageSetID(message set ID), greater than 24 characters was given.
Code Unable to store response.
Request ID

If you include a request ID in a request message, that ID will be returned in a status check request. This is a handy way to identify a request that was sent earlier.

Comparing requests (performing a checksum)

In certain cases when you send multiple requests with the same newMessageSetID, QuickBooks compares the two versions of the messages themselves by performing a checksum on them. If the messages do not match, QuickBooks returns an error (9001) because, even though the newMessageSetIDs were the same, the messages were different, so your intent is not clear. (If the messages match, then QuickBooks assumes you’re performing a status check.)

Status for individual requests within a message set

When a message set contains multiple requests, some of the requests may have been processed successfully before the error condition occurred. When error recovery is implemented (through use of newMessageSetID), applications integrating with QuickBooks receive individual status codes for each request within the message set, as shown below:

<QBXML>
<QBXMLMsgsRs newMessageSetID="DE9437D9-AA85-21E4=D643"
messageSetStatusCode="0">
<CheckAddRs requestID="345" statusCode="510" statusSeverity="Warning" statusMessage="Unable to return all data" />
<AccountAddRs requestID = ”346” statusCode = "0" statusSeverity = "Info"
statusMessage = "Status OK" />
<CustomerModRs requestID = ”347” statusCode = "0" statusSeverity = "Info"
statusMessage = "Status OK" />
<CheckAddRs requestID="348" statusCode="3231" statusSeverity="error"
statusMessage="This request has not been processed" />
</QBXMLMsgsRs>
</QBXML>

This example contains the following status information:

Clearing state (oldMessageSetID)

Once you know that a particular request has been processed successfully, you’ll want to delete your saved copy of the request and send a message to QuickBooks to clear the old message set ID and associated status information that has been stored. The next example shows one way to clear the oldMessageSetID and status information:

<QBXML>
<QBXMLMsgsRq oldMessageSetID = "DE9437D9-AA85-21E4-D643"
onError = "continueOnError"/>
</QBXML>

The following table lists uses of new and old message set IDs:

If your request includes … QuickBooks does this

messageSetStatusCode

returned …

A brand new

newMessageSetID.

Executes the request and stores state for this message ID status=0.
A newMessageSetID that has already been sent in a previous message. Status check. (Also does checksum on the two messages that use the same newMessageSetID.)

If checksum is OK, returns status=0.

If checksum fails, returns status=9001.

oldMessageSetID = newMessageSetID

(Both are included in same request; ID has already been sent in a previous message.)

Status check.

status=0

(If ID can’t be found, returns status 9002).

Only an oldMessageSetID. Clears state for this message ID.

status=0

(If old ID can’t be found, returns status=600;).

oldMessageSetID =ClearAllMessageSets If you receive status code9005, issue this request, whichdeletes all recovery records forthis application. status=0 if the records aredeleted. (If no recordsexist to be deleted or anerror occurs duringdeletion, returnsstatus=600.)

oldMessageSetID =XXX

newMessageSetID =YYY

(oldMessageSetID was sentpreviously and newMessageSetIDis new.)

Clears state for the oldMessageSetID.

Executes the request.

Stores state for the newMessageSetID

status=0;
Maintaining state within your application

What constitutes an application’s internal state in regard to error recovery will vary from one application to another based on how the application uses and stores request and response data. For instance, many applications maintain temporarily the following information:

If the ProcessRequest call completed successfully, an application should process the returned response, handling all status codes and data.

Clearing error recovery records maintained by QuickBooks

QuickBooks maintains a finite number of error recovery processing records for your application in association with the company file that your application is modifying. If an error condition occurs that interrupts processing, your application can retrieve this stored information because it is associated with the message ID you specified along with the request message set to be processed.

The best practice to follow is to always clear error recovery processing state information from QuickBooks when your application is entirely finished with the response to the request.

For all requests except the one during which the error condition occurred, an application should already have complete information on the processing state of the request. The application might either have received that information in a normal response from QuickBooks or it might have sent QuickBooks a check status request to obtain the information. Thus, the information stored in QuickBooks for these requests is no longer needed for error recovery.

If your application does not regularly clear the processing state for requests maintained by QuickBooks, QuickBooks will eventually delete older records to allow for addition of new ones. Just as an operating system must clear memory from time to time to free up system resources, QuickBooks must ensure that resources are available for addition of new error recovery processing state records to accommodate new requests.