One of the case I seen recently is the use of SalesFormLetter.
The SalesFormLetter class has its own error handling, if it hit an error for current record (Eg. Sales order), it will handle the error and then move on with the next record. But this error handling is broken by another batch job development (a pair of outer ttsbegin & ttscommit).
Below are the details:
- Developer duplicate the Tutorial_RunBaseBatch class
- Modify it for a batch job development by putting them in .update() method and this method is wrapped by a pair of ttsbegin & ttscommit
- This development perform some business logic and at the of of the process, calling SalesFormLetter class to do Picking list (Eg. Picking list of many different sales order)
- A few orders processed, pick list printed
- After several orders are posted, it reached an order that cause error
- The error jump out to the inner most try...catch... block that's outside of the ttsbegin & ttscommit, this cause the try...catch... block inside SalesFormLetter not catching it, hence, not moving on to next order and posting stopped
- All previously posted picking list is rolled back
- Warehouse guy try to pick the item but picking list not found in the system (due to rolled back)
This issue happen because any error occur within a ttsbegin & ttscommit pair will not be catch by the try...catch... block within the transaction pair, it will jump out to the inner most try...catch block outside of the transaction pair.
Refer to this link for more details: http://msdn.microsoft.com/en-us/library/aa893385(v=ax.50).aspx
Example below shows an error occur in SalesFormLetter will not be catch by its try...catch... block, instead, it will jump out to the try...catch... block at the .run() method.
//Code modified to make this easier to read, but should
//roughly explains what this article is trying to achieve
public void run()
{
try
{
ttsbegin;
this.update();
ttscommit;
}
catch
{
}
}
public void update()
{
SalesFormLetter salesFormLetter;
;
//Eg. Some business logic for batch job
this.someOtherMethod();
this.someOtherLogic();
//Eg. Post a few picking list at the end
salesFormLetter = SalesFormLetter_PickingList::construct(true);
salesFormLetter.proforma(false);
salesFormLetter.printFormLetter(true);
salesFormLetter.updatePrinterSettingsFormLetter(..., ...);
salesFormLetter.parmMarkedLines(true);
salesFormLetter.parmPostBatchMode(true);
salesFormLetter.parmInventLocationMarked(...);
salesFormLetter.update(...);
}
When developing error handling, it is important to consider the other classes that will be called and investigate further whether it will break it or develop a mechanism to handle it properly.
No comments:
Post a Comment