SoapFault vs Exceptions

When working against complex soap servers from PHP it’s generally a nice thing to be able to act on exceptions and not just provide the error message. I’ve been working against X-Fire web services for the last few months, and every time an exception is thrown it’s returned as a SoapFault with the actual exception name as property in the detail field. I wanted proper exceptions which I could do something useful with, so I poked around and came up with something which fixes this. The basic idea is to catch the soap fault exception, parse it for information and build a new exception based on the name which is retrieved. The code is a bit gritty since the actual name of the exception is a field, but that’s nothing that reflection can’t solve. The doRequest method is the method used to call the web service methods. This is a part of my soap client class.


/**
* Do the soap request
*
*/
protected function doRequest($name, $args = array()) {
try {
$response = $this->__soapCall($name, $args, $this->options);
return $response;
}
catch(Exception $e) {
$newEx = $this->buildException($e);
throw $newEx;
}
}


/**
* parses a soap fault and returns the error code and message
* used by buildException
*
* @param SoapFault $e
* @return array
*/
protected function parseSoapFault(SoapFault $e) {
$pos = strpos($e->faultstring, ':');
$code = "";
if($pos) {
$code = substr($e->faultstring, 0, $pos);
$message = trim(substr($e->faultstring, $pos+1, strlen($e->faultstring)));
} else {
$message = $e->faultstring;
}
return array($code, $message);
}


/**
* This method takes a SoapFault and builds a proper exception from it
*
* The SoapFault can hold a server side exception name in it's detail field. This
* method takes a peek to see if that field exists, and if it does the name of the
* field is extracted via reflection. A new exception is created of the class that
* was just retrieved and the message and code is set.
*
* The message and error code is extracted from the soap fault.
* @param unknown_type $e
* @return unknown
*/
protected function buildException($e){
list($code, $message) = $this->parseSoapFault($e);
if (!isset($e->detail)){ // No exception found
$ex = new GenericException($message,$code);
return $ex;
}


// get the actual name of the exception
$reflectionObject = new ReflectionObject($e->detail);
$properties = $reflectionObject->getProperties();
$exceptionName = $properties[0]->name;


$exception = new $exceptionName($message,$code);
return $exception;
}

About these ads

2 Comments

  1. matt said,

    September 4, 2007 at 7:00 pm

    hey erik,
    i’ve been looking online to find out how you add a complex wsdl type to a soapfault’s details field. any idea? thanks.

  2. eirikhoem said,

    September 5, 2007 at 9:55 am

    Hi!
    When I get the soapfaults back it’s already populated for me. Which back-end are you working against / how does it handle errors?


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: