I'm working on a project where I am verifying information from a user with a SOAP web service. I currently am taking care of errors assuming that I'm receiving responses from the web service, but also need to handle the edge cases of a service timeout or unavailability.
In the case of a timeout or service unavailability, I need to pretend that the request was successful (that the web service approved the info), but I'm not clear on what exceptions are thrown.
Some pseudo-code:
// $client is PHP's SoapClient class
try {
$response = $client->SomeSoapRequest();
}
catch(SoapFault $e){
// handle issues returned by the web service
}
catch(Exception $e){
// handle PHP issues with the request
}
What I can't seem to find is:
- Are timeouts a
SoapFault
? If so, what is the best way to distinguish between a timeout error and web service issues (like a type error, etc.)? I found one page that mentioned an error where the message was something to the effect of "Error loading headers", but didn't mention if this was a Soap fault. - How is a service unavailability potentially going to happen? A PHP exception seems like it would make sense (a SoapFault would be returned from the web service where unavailability would be a socket issue or similar)?
- Is there an existing service (e.g. example) that I can test a timeout against? Most timeout related discussions seem to be related to preventing timeouts by extending the default timeout setting, which isn't ideal in this situation.
just use the "stream_context" to set the timeout setting also for WSDL loading (you need to set the SoapClient $options['connection_timeout'] before):
To deal with timeouts in the service
Simply setting the
default_socket_timeout
globally via the ini may not do what you want. This would affect SOAP requests, but would also affect other outgoing connections, including DB connections. Instead, override SoapClient's __doRequest() method to make the HTTP connection yourself. You can then set your own timeout on the socket, detect it, and throw exceptions that you can trap and handle.Looks like
default_socket_timeout
is not taken into account when making SOAP calls over HTTPS:Bug open at the time of writing. As a comment on the blog post Robert Ludwick referenced in a deleted answer Timing Out PHP Soap Calls (21 Oct 2009; by Published by Robert F. Ludwick) points out, the workaround the post discusses (overriding
SoapClient::__doRequest()
with a curl request) works around this bug also.Another related bug is:
The code mentioned in the blog post has undergone some changes and can be found in it's latest form with support of HTTP authentication here on Github:
In any case, the workaround shouldn't be needed any longer as this problem has been fixed in the PHP SOAPClient extension.
I used two factors to get my SoapClient extention to throw a nice exception. The message and the time the request took to return. I think the error message "Error Fetching http headers" can also occure in some other cases, therefore the time check.
The following code should be about right
I then use SoapClientWithTimeout
To debug your service timing out. Add the following line before calling the service
From my experience, if
$e->getMessage
is "Error Fetching http headers", you are dealing with a network timeout.If
$e->getMessage
is something like "Cannot connect to host", the service you are trying to reach is down.Then there is "Looks like we got no XML document", which is more cryptic an can mean different things.