SoapClient manage error / exception - php

I'm using a soap service that is unavailable today. It's returning a 403 Forbidden code, and then I got this message :
Uncaught SoapFault exception: [WSDL] SOAP-ERROR: Parsing WSDL: Couldn't load from...[MY URL]
How can I catch this SoapFault ?
Here is my code :
$client = new SoapClient($myurl);
I also tried to use the 2nd cosntructor argument with trace and exception(s) (with and without s, saw the two versions on the net. Can't find the doc).
I tried to catch the thrown error using
catch (SoapFault $exception) {
wtf($exception->getMessage());
}
or
catch (Exception $e){
wtf($e->getMessage());
}
(As seen in official doc comments)
Nothing works. Still this Fatal Error and SoapFault uncaught.
I also tried # before new SoapClient,
and catch with and without backslash (because i'm in a namespace).
At this point, I don't know what to do to handle this error properly.
Maybe a chicken sacrifice.

Resolved, the right way is in fact
['exceptions' => true]
And the exception must be caught with
catch (\SoapFault $exception) {
wtf($exception);
}

Related

php exception not raised of fatal error,such as "class not exist"

I suppose that the exception system of PHP will catch all. but it doesn't.
try{
$obj = new Asdfasdfasdf()
} catch(Exception $e){
trace(...something...)
}
But it doesn't catch this kind of error, and I have searched php document, which didn't say which kind of exception/error is catch-able in try,catch clause.
So, how can I know that which kind of exception/error will be catched by my catch clause ?
P.S.
I finnally understand the 'error' from php engine is not the 'exception' from use land code. If you want use exception to handle engine 'error', you should manually wrap all 'error' in exception.
If you want to throw an Exception in the event that a class does not exist it, you could use class_exists().
A naive example might look something like:
function createClass($class)
{
if (!class_exists($class)) {
throw new Exception(
sprintf('Class %s does not exist', $class)
);
}
return new $class;
}
try {
$asdfasdfasdf = createClass('Asdfasdfasdf');
} catch (Exception $e) {
echo $e->getMessage();
}
From my experience, most PHP frameworks throw some sort of exception when a class is not found - for example, Symfony2 throws a ClassNotFoundException. That said, I don't know if you can 'catch' that, it's probably really just a development aid.
PHP 7 has just been released and from what I understand from the spec, you will be able to catch a fatal error as an EngineException. I don't know if it would work for your example; I haven't tested it because I have not installed PHP 7 stable yet. I tried your example with an alpha release of PHP 7 on an online REPL, and it appears that it does not work.
However for completeness, here's an example from the RFC:
function call_method($obj) {
$obj->method();
}
try {
call_method(null); // oops!
} catch (EngineException $e) {
echo "Exception: {$e->getMessage()}\n";
}
// Exception: Call to a member function method() on a non-object
In any case, as noted by #MarkBaker and #MarcB in the question's comments, you cannot "catch" a fatal error in previous versions of PHP.
Hope this helps :)

Restart Code after Uncaught Exception?

I'm not very smooth with PHP, because I'm only using it temporary. The nature of my code is very simple, and it does have a few cases where it comes to a "uncaught exception: exit".
How exactly can I use the exception handler to tell it restart the code when it gets this error?
See: http://php.net/manual/en/language.exceptions.php
Use try-catch statement:
try {
//your code here
} catch (Exception e) {
// do something if an exception is thrown.
}

I am unable to catch exception in php code

I have following piece of code:
function doSomething()
{
try {
doSomeNastyStuff() // throws Exception
} catch(\Exception $e) {
if ($this->errorHandler) {
call_user_func($e);
} else {
throw($e);
}
}
}
However, the catch block does not work. The stack trace shows me the error happened at the line doSomeNastyStuff(). Where is the problem?
The problem is, you are rethrowing your Exception. The stack trace is part of the Exception instance and is recorded at the moment, exception is created. You can get the stack trace by
$e->getTrace(); // Exception $e
When you rethrow exception in your code, it still has the old stack trace recorded and this tricks your framework to show you, the exception actually happened at the line doSomeNastyStuff() and it seems like the catch does not work.
Therefore, it is better idea to rethrow exceptions the following way:
/** instead of throw($e) do */
throw new \Exception("Unhandled exception", 1, $e);
Beginining with php5.3, Exception constructor has optional third parameter $previous exactly for this purpose. You can then get the previous Exception using $e->getPrevious();

Uncaught OAuthException error

A few days ago my app was working fine. Now I'm getting this error after the user tries to authenticate it:
Fatal error: Uncaught OAuthException: (#1) An unknown error occurred thrown in /home/.../public_html/..../src/base_facebook.php on line 1024
all of a sudden i am seeing this and traffic is falling a lot because people can't use the app.
use try {} catch block, example :
try {
$user_profile = $facebook->api('/me');
} catch (FacebookApiException $e) {
die($e->getMessage());
}
Then you can find out how to catch it... and you can provide us more info

Checking a URL is valid (from php soap client)

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.
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.
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

Categories