The following code will incorrectly print "BUG":

xmlrpc('foo', ...); // fails, and returns an XML-RPC error
xmlrpc('bar', ...); // succeeds
if (xmlrpc_errno()) {
  print "BUG";
}
else {
  print "OK";
}

The problem is that the XML-RPC error is cached in a static variable and that it is not cleared after a successful XML-RPC call. This makes it impossible to use multiple XML-RPC calls in a reliable way.

CommentFileSizeAuthor
#3 clearxmlrpcerrjv.patch1.27 KBjvandyk

Comments

Anonymous’s picture

This is by design:

/**
 * Returns the last XML-RPC client error number
 */
function xmlrpc_errno() {

The proper, reliable way to use multiple XML-RPC calls is to wrap them in a try/catch block. For example:

<?php
function XmlRpcException()
{
    if(xmlrpc_errno()) {
        throw new Exception('An error has occured');
    }
}

try {
  xmlrpc('foo', ...); // fails
  XmlRpcException(); //throws exception
  xmlrpc('bar', ...); //never gets here
  XmlRpcException();
}
catch(Exception $e)
{
  echo 'Caught exception';
}
?>

I think that however the proper way to handle this would be to modify xmlrpc so that it will throw an exception on failure, rather than simply setting a static variable. Unsetting the static variable could be problematic, as there may be contributions which are using xmlrpc_errno() in a way which checks to see if anything in a series of XML-RPC calls has failed.

Anonymous’s picture

Status: Active » Closed (works as designed)
jvandyk’s picture

Status: Closed (works as designed) » Needs review
StatusFileSize
new1.27 KB

Patch adds a reset function to xmlrpc_error(). boydjd, I think the caller would be responsible for keeping track of the success/failure of xmlrpc() calls.

Anonymous’s picture

Regardless of who or what should be responsible for keeping track of the success/failure of xmlrpc() calls, as long as we're not modifying xml-rpc core then we should be okay.

+1 on the patch, applied against HEAD and works properly.

vladimir.dolgopolov’s picture

Status: Needs review » Active

It seems the same problem:

XMLRPC library does not reset xmlrpc error code before a new xmlrpc call is requested
http://drupal.org/node/56715

Anonymous’s picture

Status: Active » Closed (duplicate)

Agreed, duplicate with duplicate patch.

Anonymous’s picture

Status: Closed (duplicate) » Needs review

I take that back, the other patch resets the error code every time a call is made, which is not desired functionality.

dries’s picture

Related problem. In common.inc we do:

if (!$fp) {
$result->error = trim($errno .' '. $errstr);
return $result;
}

Note that $result->code is not set!

Then in xmlrpc.inc we do:

$result = drupal_http_request($url, array("Content-Type" => "text/xml"), 'POST', $xmlrpc_request->xml);
if ($result->code != 200) {
  xmlrpc_error(-$result->code, $result->error);
  return FALSE;
}

Because $result->code is not set, no xmlrpc_error() is set either.

dries’s picture

Specifically, I have an xmlrpc() call that results in a "111 Connection refused" but that error does not propagate to the XML-RPC layer due to the above mentioned bug.

gerhard killesreiter’s picture

Version: 6.x-dev » 7.x-dev
Priority: Normal » Critical

This patch is clearly needed for successful usage of Drupal's xmlrpc library. It applies to D5, 6 and 7 and should IMO be applied to all three.

dries’s picture

Version: 7.x-dev » 6.x-dev
Status: Needs review » Reviewed & tested by the community

I've tested this patch and committed it to CVS HEAD. I also believe it is ready to be committed to DRUPAL-6 but I'll leave that up to Gabor to decide.

gábor hojtsy’s picture

Version: 6.x-dev » 5.x-dev

Agreed. I've added a newline at the end of the xmlrpc.inc file so CVS is happy, and committed that. Also applies to Drupal 5.

drumm’s picture

Status: Reviewed & tested by the community » Fixed

Committed to 5.x.

Anonymous’s picture

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for two weeks with no activity.