Very weird SoapClient problem - php

try
{
$client = new \SoapClient($wsdlUrl, array(
'cache_wsdl' => 0, 'exceptions' => true, 'trace' => true));
$client->getPage($parameter);
}
catch(\Exception $e)
{
die("exception");
}
Okay this is what executes the SOAP request. $wsdlUrl holds the WSDLs URL and $parameter keeps an XML document.
And everything works like a charm!
Now I just add few more nodes to the XML document in $parameter and I get a fatal error.
This is not so weird necessarily, but what is weired is the combination of following three observations:
1) exceptions is set to true .... but no Exception is thrown / this was b/c I forgot to place a backslash before Exception in the catch statement.
2) instead an error is logged:
PHP Fatal error: SoapClient::SoapClient():
'uri' option is required in nonWSDL mode in /var/w[...]
3) but the WSDL url is provided and of course valid, as all works again just fine after skipping the adding of the new nodes. they don't affect the wsdl parameter.

Okay, I tracked down the source of the problem. There is no satisfying answer really to that question but few things to learn! :)
The important thing is that the request has been sent and processed by the SOAP server.
But the server responds with an error.
So, obviously, even though a fatal error regarding no wsdl and no connection parameter is triggered doesn't mean no request has been sent - which is very counter logical in my opinion b/c if no wsdl is provided and no connection params as well, then how could the request be executed?
EDIT
There is another bug in the code. I forgot to place a backslash before Exception! Without it's not referring to the Exception class.
Then an exception is thrown and caught.

Related

PHPUnit Assertions project

I am working on a PHP project that requires validating a JSON request to a predefined schema, that is available in swagger. Now I have done my research and have found that the best project for this is SwaggerAssertions:
https://github.com/Maks3w/SwaggerAssertions
Within SwaggerAssertions/tests/PhpUnit/AssertsTraitTest.php, I would love to make use of the testAssertRequestBodyMatch method, where you do this:
self::assertRequestBodyMatch($request, $this->schemaManager, '/api/pets', 'post');
This assertion above does exactly what I need, but if I pass a invalid request it causes a fatal error. I want to trap this and handle the response back rather than the app quitting altogether.
How can I make use of this project, even though it looks like its all for PHPUnit? I am not too sure how one would make use of this project in normal PHP production code. Any help would be greatly appreciated.
Assertions throw exceptions if the condition is not met. If an exception is thrown, it will stop all following code from being executed until it's caught in a try catch block. Uncaught exceptions will cause a fatal error and the program will exit.
All you need to do to prevent your app from crashing, is handling the exception:
try {
self::assertRequestBodyMatch($request, $this->schemaManager, '/api/pets', 'post');
// Anything here will only be executed if the assertion passed
} catch (\Exception $e) {
// This will be executed if the assertion,
// or any other statement in the try block failed
// You should check the exception and handle it accordingly
if ($e instanceof \PHPUnit_Framework_ExpectationFailedException) {
// Do something if the assertion failed
}
// If you don't recognise the exception, re-throw it
throw $e;
}
Hope this helps.

SOAP: HTTP Not Found when parameter is "SELECT sth FROM"!

I' ve a problem with Soap (I'm using it for the first time!).
I'm trying to solve a problem with SOAP, used to communicate between my site and another.
In SoapServer (on my site) I have a function called say_hello() that takes no argument and returns simply "hello", if I call it from a SoapClient, also with an argument, it works well.
The problem appears if the argument passed is "SELECT everythingyouwanthere FROM otherthingifyouwant". I don't know why but it returns "PHP Fatal error: Uncaught SoapFault exception: [HTTP] Not Found" (404 error).
This started to happen suddenly (or, at least, I don't know the causes). On the server PrestaShop is installed.
Thanks in advance!
P.S. Sorry for my bad english!
try to pass the argument through an array.
Instead of
...
$client = new SoapClient(WSDL);
$client->say_hello("SELECT everythingyouwanthere FROM otherthingifyouwant");
...
try
...
$client = new SoapClient(WSDL);
$client->say_hello(array("parameter_name" => "SELECT everythingyouwanthere FROM otherthingifyouwant"));
...

Facebook PHP SDK Throwing an Uncatchable OAuthException

I'm attempting to post an open graph action to the Facebook Graph API but receiving an OAuth Exception (#3501) User is already associated to the <object>. That's all well and good, I expect Facebook to throw that exception. I get some other exceptions regarding authenticating a user (maybe with old/stale sessions, whatever).
My question is, has anyone else experienced that this exception is uncatchable in php? In this specific example (of posting graph actions) I am absolutely wrapping the call to the api in a try/catch statement; but I still get the fatal error.
<?php
try {
//publishing to open graph
$this->fb->api('/me/app:action', 'POST', array(
'object' => 'http://www.domain.com/path/to/graph/object',
));
}
catch (Exception $e)
{
/*
We may get here if the user has already posted this action before...
or if our session somehow went sour
or bc facebook is down...
or one of any other 1000 reasons the graph api is currently
sucking...
in any case it doesn't much matter, this is not a mission critical
thing to worry about; if we don't post the graph action - we don't
post the graph action..nbd.
*/
}
The above code is the snippet the publishes the graph action (generalized, because the content of it isn't important to this example).
I realize that the Exception that the Facebook PHP SDK is throwing is a FacebookApiException but that class extends Exception. I can't for the life of me figure out why in the name of all things logical, I can't catch my exception like this.
Has anyone experienced this issue? Is this a bug in the FB PHP SDK? Am I missing something else here? Thanks for your help!
Also, for reference, the relevant parts of the FB PHP SDK are here:
FacebookAPIException Definition (base_facebook.php line 30)
Throwing OAuthException (base_facebook.php line 1105
Edit 5/1/12
After some more investigation, it turns out that this "Exception" isn't really being treated like an exception at all. Typical Exceptions print out a stack trace back to the method call which resulted in throwing the exception. These "OAuthExceptions" do not. Also, typical exceptions pring out their error string a bit differently, for example:
PHP Fatal error: Uncaught exception 'Exception' with message 'foo' /path/to/file.php:10
or
PHP Fatal error: Uncaught exception 'MyException' with message 'stupid php' /path/to/file:10
#0 /path/to/file.php(17): doTest()
#1 {main}
thrown in /path/to/file.php on line 10
In this particular case, we don't get any of that, and it looks much more like a typical fatal error:
PHP Fatal error: Uncaught OAuthException: (#3501) User is already associated \
to the <object> object on a unique action type <action>. Original Action ID: \
123123123
thrown in /path/to/app/libs/fb/base_facebook.php on line 1107, \
referer: http://www.domain.com/path/to/page
I can't make any sense of why this forsaken "Exception" is so weird/uncatchable.
The Solution:
I figured out the answer to my own question; I've added it below - it's developer error, not a bug. The answer is below.
Also, this very well could be part of a bug, if you wanted to say that being able to reference a class definition as a type-hint to the catch definition which didn't exist (or wasn't available in the current namespace) is a bug.
So, something that's not outline above is that I'm utilizing PHP namespaces. This is a big gotchta since namespaces are relatively new to php, it's super easily overlooked I feel. Regardless, it's a pretty silly oversight/error.
If you're in a defined namespace (that is, not the root (\) namespace) you don't have direct access to the Exception class. Instead of php throwing a warning about not knowing what that class is, it just ignores the fact that it doesn't know what it is - and doesn't catch the exception.
Solution 1:
import the exception class:
<?php
use \Exception;
// ...codes
try {
//...codes
}
catch (Exception $e)
{
//...codes
}
Solution 2:
provide the full path to the exception class:
<?php
try {
//.....
}
catch (\Exception $e)
{
// voila.
}

How do I view the last request from Zend_Soap_Client->getLastRequest() after a soap fault exception?

I am using a Zend_Soap_Client to call a web service. I am getting an exception from the error which I suspect is down to me not sending something along with the request:
Fatal error: Uncaught SoapFault exception: [Sender] SOAP-ERROR:
Encoding: object hasn't 'V24Flag' propert
Because it throws an exception I want to try view what is the actual request being sent, however because of the exception, I can not use Zend_Soap_Client->getLastRequest() to get the request (it returns null). Looking at the Zend_Soap_Client->getLastRequest() its a thin wrapper for soapClient->__soapCall() which I'm not sure how to dig deeper from.
Your problem is actually slightly different to what you think it is. The reason Zend_Soap_Client::getLastRequest() returns NULL for you is that no request was ever made: the error is being thrown at the stage where the request internally is being compared against the WSDL you are using. So the method is perfectly correct to return NULL.
As to how to form the parameter for your SOAP call so this error isn't thrown, I can't be of much greater help right now (I expect it depends partly on the services you are integrating with), but there's a userland answer on the php.net page for SoapClient::__soapCall() which may point you in a fruitful direction. Essentially, some people seem to have got somewhere by doing a deep conversion of an array structure into stdClass objects. That doesn't seem to be the whole story (it isn't for the issue I'm currently investigating), and indeed this may be down to a bug in PHP, but I hope it helps you towards an answer.
How about
try {
$client = new Zend_Soap_CLient();
$client->doSomething($params);
} catch(SoapFault $f) {
echo $f->getTraceAsString();
}
Btw. Zend_Soap_Client->getLastRequest() wraps SoapClient::__getLastRequest();

Catching Kohana_Request_Exception in Kohana v3 during execution -- unexpected behaviour

As detailed here: Need assistance with Kohana 3 and catch all route turning into a 404 error as the accepted answer to the question, I'm attempting to catch errors thrown by Kohana to display pretty error pages and send correct HTTP codes.
Here's a simplified version to demonstrate the problem:
try {
// Instantiate your Request object
$request = Request::instance();
// The give it a try, to see if its a valid request
$request->execute();
}
catch (Kohana_Request_Exception $e) {
header('Content-Type: text/html; charset='.Kohana::$charset, TRUE, 404);
echo Request::factory('err/404')->send_headers()->execute()->response;
exit;
}
echo $request->send_headers()->response;
So I navigate to a non-existent URL such as http://example.local/moo/ and I get the following response
Kohana_Request_Exception [ 0 ]: Unable to find a route to match the URI: moo
Here is what's happening-- The request is being tried, failing with a Kohana_Request_Exception, it's being caught BUT when I try to build a new request object, Request::factory('err/404') THAT request throws the error from my first request....!? wtf??
I've fiddled with it for a good hour and am as puzzled as when I started. Shouldn't the new request from the factory have no knowledge of the old request?? Why is this code malfunctioning when I essentially copied it from the d00d's answer?
// Release version and codename
const VERSION = '3.0.7';
const CODENAME = 'hattrick';
Someone point me in the right direction.. thx guys.
It's because within Request::factory('err/404'), the err/404 part is a URL that is trying to be matched by your routes as well. Will it ever match, i.e. do you have a route with something like this...
Route::set('errors', 'err/<action>', array('action' => '404|500')) {}
You should also be sending a 404 via...
$request->status = 404;
Aha! Thanks guys but I got it figured.. I shoulda looked at the stack trace a little closer, the error page's template controller's before() method was throwing a new error as it was attempting to check authentication using Request::instance()I changed it to Request::current() and it's all shiny.
Thanks for the help!

Categories