0

We've developed an integration with a series of APIs provided by a third-party into a child-theme of Divi. In functions.php of that child-theme, we've created a series of functions for the purpose of generating shortcodes to return certain parts of data from the API in various areas of the template.

The code for these functions was written in the third quarter of 2019. No changes have been made to the source code but as of the middle of January, we are getting frequent (on the tune of several times a day) PHP fatal errors like the following:

PHP Fatal error: Uncaught Error: Cannot use object of type WP_Error as array in /nas/content/live/client/wp-content/themes/theme/functions.php:292
Stack trace:
#0 /nas/content/live/client/wp-includes/shortcodes.php(325): 
get_one_job_title('', '', 'get_one_j...')
#1 [internal function]: do_shortcode_tag(Array)
#2 /nas/content/live/client/wp-includes/shortcodes.php(199): preg_replace_callback('/\\\\[(\\\\[?)(get_on...', 'do_shortcode_ta...', '[get_one_...')
#3 /nas/content/live/client/wp-content/themes/theme/functions.php(716): do_shortcode('[get_one_...')
#4 /nas/content/live/client/wp-includes/class-wp-hook.php(290): client_shortcode_titles('[get_one_...')
#5 /nas/content/live/client/wp-includes/plugin.php(206): WP_Hook->apply_filters('[get_one_...', Array)
#6 /nas/content/live/client/wp-includes/general-template.php(1345): apply_filters('single_post_tit...', '[get_one_...', Object(WP_Post))
#7 /nas/content/live/client/wp-content/themes/divi/epanel/custom_functions.php(1094): single_pos in /nas/content/live/client/wp-content/themes/theme/functions.php on line 292

In an attempt to understand a bit more on what's going on, we're using a check for is_wp_error and get_error_messages if triggered. That results in the following:

<!-- Array ([0]=> http_request_failed): Array([0]=>cURL error 28: Operation timed out after 5000 milliseconds with 0 bytes received) -->

To provide code context, here is functions that wraps line #292:

function get_one_job_title() {
    global $ApiUrl;
    global $ApiAuth;

    $position_id = get_query_var( 'position_id' );
    $get_url     = $ApiUrl . '/reqs/' . $position_id;

    if ( preg_match( '/^c-(.*)$/i', $position_id, $matches ) ) {
        $position_id = htmlspecialchars_decode( $matches[1] );
        $get_url     = $ApiUrl . '/reqs/custom/' . $position_id;
    }

    $headers['API-Realm']     = 'CCAPI';
    $headers['Authorization'] = $ApiAuth;
    $request                  = new WP_Http();
    $response                 = $request->request( $get_url, array(
        'method'  => 'GET',
        'headers' => $headers
    ) );

    $return = "";
    if(is_wp_error($response)) {
        print "<!-- CER: ".print_r($response->get_error_codes(),TRUE).": ".print_r($response->get_error_messages(), TRUE)." -->";
    }
    if ( $response['response']['code'] == 200 ) { <!-- this is line #292 -->
        $data = json_decode( $response['body'] );
        $return .= $data->JobTitle;
    } else {
        //$return .= "Error: ".__LINE__;
        $return .= "No Matching Jobs";
    }
    return $return;
}

And here is the function that wraps line #716:

add_filter( 'the_title', 'client_shortcode_titles' );
function client_shortcode_titles( $title ){
    return do_shortcode( $title );
}
add_filter( 'single_post_title', 'client_shortcode_titles' );

The host has stated that they don't believe this is a problem with their servers and believe the issue falls on the third-party API. The API company has confirmed the following:

  • No outages that match our error logs
  • No changes to their API since our deployment
  • No rate limiting on successful API calls

What else should we be looking for? Is this an API issue?

1 Answer 1

0

Lots of possible causes obviously - DNS, routing, firewall, an issue with their server or app, or an issue with your server or app.

One possible issue on their end that you could easily identify - if they're using round-robin DNS queries for the api hostname, maybe one of the api endpoints is broken and your request fails when it hits that endpoint. This problem is not uncommon and is fairly easy to identify. For a smaller service, they probably use just one IP for all requests and this is less likely an issue.

Can you reproduce failures outside of WP/PHP? Create a simple, non-PHP, command line script that logs the output and total time of a DNS query for the api server hostname, plus the output and total time of a simple GET request to the api via curl (linux cli curl - not PHP curl) or wget. Run it a few times - does it work? Run it frequently from cron - does it also fail occasionally? Do those failures coincide with the times wordpress' requests also fail?

Additionally, it may be helpful to log PHP curl verbose output. Maybe try copying the function WP_Http_Curl::request https://developer.wordpress.org/reference/classes/wp_http_curl/request/

to functions.php as request_debug(). Within that function, enable CURLOPT_VERBOSE and use CURLOPT_STDERR to capture that output as described here https://stackoverflow.com/questions/3757071/php-debugging-curl

Use request_debug() in your plugin and see what it captures.

HTH

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.