BOI SETVALUE/CLEAR Error Handling

Hello,

We recently ran into a problem while importing AP invoices as a batch. Here is a summary of our code in C#:

// Loop though AP invoices a batch

foreach (var invoice in batch.NonInventoryInvoices) {
    try {

       service.Call("nCLEAR");
       service.SetKeyValue("APDivisionNo$", invoice.APDivisionNo);
       service.SetKeyValue("VendorNo$", invoice.VendorNo);

       service.SetValue("InvoiceAmt", invoice.Total);
       service.SetValue("NetInvoiceAmt", invoice.Total);

        ... Set all other values

     } catch (Exception exception) {
        var exceptionWithInformation = service.AddErrorInformationTo(exception);  // Grabs sLastErrorNum and sLastErrorMsg

         ...

     }

     ...

}

And in service, methods such as `Call` and `SetValue` are wrapped in a try catch so that it will catch the `TargetInvocationException` thrown through reflection method.

Here is the scenario that we couldn't figure out:

In a batch of invoices, for Invoice Number 1: the BOI throws an error for a legitimate reason, for example the vendor doesn't exist, the TargetInvoicationException's inner exception would be : "<Error: 0 in Method SETVALUE>" and sLastErrorNum is "CI_Required" and sLastErrorMsg is "The Vendor Number is required." . This is totally understable and we swallow the exception and continue to try to import the next invoice.

The problem is for all the subsequent invoices, the call fails at `service.Call("nCLEAR");`, the inner exception for TargetInvoicationException's is '{"<Error: 0 in Method CLEAR>"}' and the sLastErrorNum and sLastErrorMsg is the same.

The reason for us calling `CLEAR` at the beginning of each invoice is that we had a bug before where in a batch of invoices, one invoice fails and the subsequent invoice inherent ed information from the previous invoice, so we make sure CLEAR is performed before entering each invoice.

Thank you for your help!

Tom

Parents
  • 0

    I'm not very familiar with C# but if you are trying to clear the values from sLastErrorMsg and nLastErrorNum, you actually can just set those properties after you catch your error and handle it or before you expect an error to occur. So it would be service.sLastErrorMsg = "" and service.nLastErrorNum = 0.

    Svc and Bus objects should inherit the nClear method from SY_Service and it clears the IOLIST for the current record so it would be service.nClear(). 

    The Sage 100 BOI is very sensitive to data types, especially when dealing with strings and numbers and you have to be careful to make sure that you prefix a method or property with the correct prefix for the data type returned, it also is a good practice to set the value of a variable intended to be used with GetValue to either 0 for a numeric field or "" for a string field before you use the variable in the GetValue method. You may want to review what's happening with the data types when you use the method with service.Call and also check to make sure you are resetting the sLastErrorMsg and nLastErrorNum properties after handling an error so you aren't checking those properties after catching the error and seeing a false positive. It could be that nClear method is failing because a record is not currently loaded so it may be returning a -1 or 0 but not setting the sLastErrorMsg and nLastErrorNum to meaningful values and if you are not resetting them yourself, you are likely see the last values from when the vendor wasn't on file.

    Hope this helps. 

Reply
  • 0

    I'm not very familiar with C# but if you are trying to clear the values from sLastErrorMsg and nLastErrorNum, you actually can just set those properties after you catch your error and handle it or before you expect an error to occur. So it would be service.sLastErrorMsg = "" and service.nLastErrorNum = 0.

    Svc and Bus objects should inherit the nClear method from SY_Service and it clears the IOLIST for the current record so it would be service.nClear(). 

    The Sage 100 BOI is very sensitive to data types, especially when dealing with strings and numbers and you have to be careful to make sure that you prefix a method or property with the correct prefix for the data type returned, it also is a good practice to set the value of a variable intended to be used with GetValue to either 0 for a numeric field or "" for a string field before you use the variable in the GetValue method. You may want to review what's happening with the data types when you use the method with service.Call and also check to make sure you are resetting the sLastErrorMsg and nLastErrorNum properties after handling an error so you aren't checking those properties after catching the error and seeing a false positive. It could be that nClear method is failing because a record is not currently loaded so it may be returning a -1 or 0 but not setting the sLastErrorMsg and nLastErrorNum to meaningful values and if you are not resetting them yourself, you are likely see the last values from when the vendor wasn't on file.

    Hope this helps. 

Children
No Data