Insomanic: Andy Young's Blog

  • Archive
  • RSS

Reliability Bug in Facebook PHP API Batching Support

I recently discovered a bug in the current Facebook API PHP Client library that affects the support for batching calls which I’ve used for the Selective Twitter Status application.

The bottom line is, sometimes the call to batch.run within execute_server_side_batch() as called by end_batch() returns an empty string instead of the expected array of results from each of the batched calls. The code has the following test for an exception but this isn’t triggered in it’s current state since no specific FB exception is being returned, just the empty result:

    if (is_array($result) && isset($result['error_code'])) {
      throw new FacebookRestClientException($result['error_msg'],
                                            $result['error_code']);
    }

The symptom is a bunch of PHP warnings similar to the following as the code attempts to iterate over the empty string as if it was the expected array of results:

PHP Notice:  Uninitialized string offset:  0 in [...]/facebook/facebookapi_php5_restlib.php on line 210
PHP Notice:  Uninitialized string offset:  1 in [...]/facebook/facebookapi_php5_restlib.php on line 210

etc

In my experience the empty result has been in situations where the requested batch operations haven’t been performed, so the fix is to add a test for the empty result and to treat this as an exception. This was my hack:

 if (!isset($result[0])) {
            throw new FacebookRestClientException('Batch call returned invalid result: ' . var_export($result, true) . '; ' . var_export($xml, true), 9999);
    }

As a side note, the batching support as implemented in the current PHP API client is rather limited since if one of the batched functions returns an exception it is thrown immediately, with the result that the return values of subsequent calls are not populated and it’s impossible to know whether they executed successfully. I’ve changed the line that threw the exception to instead set the FacebookRestClientException object as the return value for the relevant call as follows:

    for($i = 0; $i batch_queue[$i];
      $batch_item_result_xml = $result[$i];
      $batch_item_result = $this->convert_xml_to_result($batch_item_result_xml, $batch_item['m'], $batch_item['p']);
      if (is_array($batch_item_result) &&
          isset($batch_item_result['error_code'])) {
        // PATCH: modify to return the Exception object as the result for this call so we can process all results/exceptions
        $batch_item_result = new FacebookRestClientException($batch_item_result['error_msg'], $batch_item_result['error_code']);
      }
      $batch_item['r'] = $batch_item_result;
    }

Hopefully this helps anyone searching Google..

    • #facebookapi
    • #dev
  • 2 years ago
  • Comments
  • Permalink
  • Share
    Tweet

Recent comments

Blog comments powered by Disqus
← Previous • Next →

About

Avatar Hi, I'm Andy. I'm an entrepreneur, a techie, a founder, a CTO, a music addict. I'm working on my startup GroupSpaces - solving the pains of membership and group management. I created Selective Tweets (the #fb hashtag). I live and work in London.

Me, Elsewhere

  • @andyy on Twitter
  • Facebook Profile
  • andyjy on Delicious
  • Google
  • Linkedin Profile
  • andyyoung on github
  • RSS
  • Random
  • Archive
  • Mobile

Copyright (c) 2009-2012 AY.. Effector Theme by Carlo Franco.

Powered by Tumblr