Quantcast
Channel: Eirik Hoem's Blog » SOAP
Viewing all articles
Browse latest Browse all 6

SoapFault vs Exceptions

$
0
0

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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
/**
* 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;
}

Viewing all articles
Browse latest Browse all 6

Trending Articles