Question

I am writing a web app which will allow the user to specify a URL for a SoapClient. I wanted to validate that php can connect to the client when the user submits a form. I thouhgt I could do this via try catch or set_error_handler (or some combination of the two). However it looks like this is not possible for fatal errors. Is there a way to get SoapClent to test a URL which won't throw an unrecoverable error?

Fatal error: SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://example.com/wibble'

I want it to flag an error as the URL doesn’t exist, but I would like to be able to catch it.

Otherwise I suppose I could try to download and validate the URL myself, but I would have thought that it would be possible to do it from the SoapClient.

Should this be a fatal error?

Edit

After reading rogeriopvl's answer I reaslise that I should have said that I had tried the 'exceptions' option to the soapclient constructor and (in desperation) the use-soap-error-handler function.

Was it helpful?

Solution

Are you using xdebug? According to this PHP bug report and discussion, the issue has been fixed at least since PHP 5.1, but this xdebug bug messes with 'fatal error to exception conversions' in a way that the exception is not generated and the fatal error 'leaks through'.

I can reproduce this locally, with xdebug enabled:

try {
  $soapClient = new SoapClient('http://www.example.com');
}
catch(Exception $e) {
  $exceptionMessage = t($e->getMessage());
  print_r($exceptionMessage);
}

This gives me the fatal error you described, without even entering the catch clause:

Fatal error: SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://www.example.com'

It works if I disable xdebug right before the call:

xdebug_disable();
try {
  $soapClient = new SoapClient('http://www.example.com');
}
catch(Exception $e) {
  $exceptionMessage = t($e->getMessage());
  print_r($exceptionMessage);
}

This triggers the exception as expected, and I get a proper SoapFault Object in the catch clause with a message of:

SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://www.example.com'

So basically exceptions work as advertised. If they don't work in your case, you might encounter the xdebug bug, or maybe a similar issue with another 3rd party component.

OTHER TIPS

Quoting SoapClient documentation:

The exceptions option is a boolean value defining whether soap errors throw exceptions of type SoapFault.

So you should try something like:

$client = new SoapClient("some.wsdl", array('exceptions' => TRUE));

This way will throw SoapFault exceptions allowing you to catch them.

See: http://bugs.xdebug.org/view.php?id=249

Possible solution:

Index: trunk/www/sites/all/libraries/classes/defaqtoSoapClient.class.php
===================================================================
--- classes/defaqtoSoapClient.class.php
+++ classes/defaqtoSoapClient.class.php
@@ -31,10 +31,23 @@

     try {
+        // xdebug and soap exception handling interfere with each other here 
+        // so disable xdebug if it is on - just for this call
+        if (function_exists('xdebug_disable')) {
+            xdebug_disable();
+        }
       //Create the SoapClient instance
       parent::__construct($wsdl, $options);
     }
     catch(Exception $parent_class_construct_exception) {
+        if (function_exists('xdebug_enable')) {
+            xdebug_enable();
+        }
       // Throw an exception an say that the SOAP client initialisation is failed
       throw $parent_class_construct_exception;
+    } 
+    if (function_exists('xdebug_enable')) {
+        xdebug_enable();
     }
   }

you could try and do a curl or fsockopen request to check the URL is valid.

For your information, i'm using SoapClient with PHPUnit to test remote WebServices and got the same problem!

  • when using an old PHPUnit version (3.3.x) as third party, phpunit crash
  • when using current version of PHPUnit (3.4.6) as third party, phpunit display "RuntimeException".

Here is my first test method :

public function testUnavailableURL() {
    $client = new SoapClient("http://wrong.URI");
}

Here is PHPUnit first result :

There was 1 error:

1) MyTestCase::testUnavailableURL
RuntimeException: 


FAILURES!

Here is my second test method :

public function testUnavailableURL() {
        try {
          $client = @new SoapClient("http://wrong.URI");
        } catch (SoapFault $fault) {
          print "SOAP Fault: (faultcode: {$fault->faultcode}, faultstring: {$fault->faultstring})";
        }
}

Here is PHPUnit second test result :

PHPUnit 3.4.6 by Sebastian Bergmann.

.SOAP Fault: (faultcode: WSDL, faultstring: SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://wrong.URI' : failed to load external entity "http://wrong.URI"
)...

Time: 3 seconds, Memory: 4.25Mb

OK

NB: i found a phpunit ticket on this subject : ticket 417

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top