api_ErrorMessages and failure then success

Sep 3, 2010 at 11:43 PM
Edited Sep 3, 2010 at 11:43 PM

I've got code that basically looks like this:

bool success = false;
while (!success)
{
    listBatchSubscribeOutput listBatchSubscribeOutput = listBatchSubscribe.Execute();

    if (listBatchSubscribeOutput.api_ErrorMessages.Count > 0)
    {
        // checks if expected timeout exception -- if so, sleep w/ increasing backoff otherwise blow up
    }
    else
    {
        success = true;
    }
}

So this all looked fine except if it fails once. Then it gets stuck in a loop of repeating. I'm in the middle of waiting on a big timeout to do some debugging so I can't actually prove this to myself yet but I'm guess that the list listBatchSubscribeOutput.api_ErrorMessages doesn't get cleared even if the API call succeeds. I'm fairly certain that is the case as I was just looking at it and it appeared the result was success on the last API call in the current debugging session. Then I accidentally hit F5 while playing with the Immediate Window and...

So after a 16 minute wait, back to Intermediate Window:

listBatchSubscribeOutput.api_ErrorMessages
Count = 2
    [0]: {Error Code: ex, Message: The operation has timed out

   at System.Net.HttpWebRequest.GetResponse()
   at PerceptiveMCAPI.apiHelper.ProcessSerialRequest(Api_BaseInput input, Dictionary`2 parameters, String& request)
   at PerceptiveMCAPI.Methods.listBatchSubscribe.ExecuteSerialPost()}
    [1]: {Error Code: ex, Message: Object reference not set to an instance of an object.

   at PerceptiveMCAPI.Methods.listBatchSubscribe.outputJSON()}

However:

listBatchSubscribeOutput.result
{Success Count: 1500, Error Count: 0}
    error_count: 0
    errors: Count = 0
    success_count: 1500

So I think I'm right but also I should be checking the value of listBatchSubscribeOutput.result.error_count. Is that correct? But I also think it is a bug that api_ErrorMessages isn't reset. Thoughts?

Sep 4, 2010 at 12:18 AM

As an update to this for anyone going down the same route: it is important to check result.error_count and likely log result.errors if error_count > 0. The tricky thing is in my batch subscribe 1498 of the addresses were successful but 2 were not due to being malformed (long story on data origin, out of my hands). So in this case I would say a bunch succeeded so I'd log the 2 errors for followup and continue onwards. Note this is separate from api_ErrorMessages.

Coordinator
Sep 10, 2010 at 1:21 PM
Edited Sep 10, 2010 at 1:24 PM

Based on your second message, I think you are starting to become more clear about how the batch commands work, but there still seems to be some misunderstanding -- both for the wrapper & the underlying MC batch api methods -- and for the rest of the crowd who might be new to this, I'll explain a little more in depth. 
------------

First, as a reminder the wrapper just makes it easier to use the MC Api, the api still works as described in MailChimp's documentation -- and an understanding of how the api methods work is needed whether you use my wrapper, someone else's, or roll your own api calls.

What my wrapper does as far as returning messages is embed two properties in the api_BaseOutput class -- api_ValidatorMessages and api_ErrorMessages.

The validator messages are only used if you set validation on, and are used to capture validation errors PRIOR to sending the api request to MC and they are not used to record any api call results.

The error messages class records two types of errors, api request results and program execution errors.
If the program execution fails, the error is captured via a try-catch block and recorded in the error messages, but the api call completes 'normally' rather than going 'yellow screen'. These errors have an 'ex' code and the error message is recorded.
If the api call is not valid (bad email address, missing data, etc.) -- as determined by MailChimp -- then error class contains the MC error code and description.

That all works fine when you are dealing with a single entity - be it a campaign, a list, or an individual subscriber -- but with the batch commands working against multiple subscribers, a means to indicate a problem against any single subscriber as well as at the api call level is required -- so MC added an array of 'errors' in the returned fields with counts of good and bad.
So, by definition of how the MC api batch methods work, the api call will not have errors, but not all the data will be successfully applied -- and yes, for batch commands you need to verify both that the api call completed normally, and THEN determine if all your data was successfully applied.

That said, cymen, the reason the api_ErrorMessages wasn't reset is that it is reset in the Output class constructor when you instantiate the 'command' class, not in the Execute() method, so you would have to put something like ...

listBatchSubscribe cmd = new listBatchSubscribe( input );

... before your ...

listBatchSubscribeOutput listBatchSubscribeOutput = listBatchSubscribe.Execute();

... to have it be reset.

I already have the change to move the Output class instantiation to the Execute() method, and some other related changes, on the project list for the next release. 

I'll describe an approach that I would suggest as being more resilient for long-running batch api calls, in separate discussion topic, within the next few days.

 

Hope that helps,

dbm

Sep 10, 2010 at 1:34 PM

That helps a lot. Thank you! And indeed I should be more careful to check the API documentation at the same time (which would have corrected my misuse before it became an issue).

Thanks again,

Cymen