wp_remote_get returns an array or a WP_Error, never both

The HTTP API returns a response array on success and a WP_Error on failure, and the two share no shape at all — so any code that reaches straight for ['body'] produces a fatal the first time the remote host is slow.

$response = wp_remote_get( $url, array( 'timeout' => 5 ) );

if ( is_wp_error( $response ) ) {
    return $response;   // network failure, DNS, timeout
}

$code = wp_remote_retrieve_response_code( $response );

if ( 200 !== $code ) {
    return new WP_Error( 'http', "Unexpected status {$code}" );
}

$body = wp_remote_retrieve_body( $response );

The second check is the one people skip: a 404 or a 500 is a perfectly successful HTTP transaction as far as the API is concerned, so is_wp_error() returns false and the body is an error page. The default timeout is five seconds, which is long enough to make a slow third party into a slow site — set it explicitly, lower, on anything in the request path.