Zend Framework 2 SOAP Fault Exception - php

I want to know what is the original exception details in my SOAP code, I have a SOAP server that handles requests as the following:
$options = array(
'soap_version' => SOAP_1_2,
'actor' => someUriAString,
'encoding' => 'UTF-8',
'uri' => someUriAString);
$server = new Server(null, $options);
$server->setClass('SomeClass');
$server->setReturnResponse(true);
$serverResponse = $server->handle();
and then I check if an exception occurs as the following:
if ($serverResponse instanceof \SoapFault) {
//log the $serverResponse exception details
}
but when I log this exception I got something like this:
exception 'Exception' with message 'SoapFault exception: [Receiver] Unknown error
the thing I need to know is the original exception details... like SQL exception, or for example ORMException,...etc. i.e. I need the exact original exception details...
I already tried to registerFaultException as following example:
$server->registerFaultException('Doctrine\ORM\ORMException');
I don't know if this is right, but the problem is that there may occur other types of exception, I can not register them since I don't know what exception could occur in my code!

It depends how the expections are setup, but you can get Previous exception message:
$message->getPrevious();
You can iterate overthem like this:
if($message instanceof \Exception) {
do {
echo sprintf(
"%s:%d %s (%d) [%s]\n",
$message->getFile(),
$message->getLine(),
$message->getMessage(),
$message->getCode(),
get_class($message)
);
}
while($message = $message->getPrevious());
}

Related

How to remove default Laravel Exception message from Custom Exception message

I have this get organisations method in one project that talks to a central api project that handles all data like so:
public function searchOrganisations()
{
try {
return $this->client->request(.....);
} catch (Exception $ex) {
}
}
Within the api project a method is then hit and if a certain time frame criteria is hit I throw a custom exception like so:
public function searchOrganisations($searchRequest)
{
$experianCutOff = Carbon::createFromFormat('H:i:s', '06:00:00');
$now = Carbon::now()->setTime(02, 0, 0);
if (!$now->lt($experianCutOff)) {
return $data
} else {
throw new ExperianServiceException();
}
}
My custom exeption is as follows:
class ExperianServiceException extends Exception
{
public function render() {
return response()->json([
'message' => 'The Experian Service is currently unavailable, please try again at 0600 GMT'
], 503);
}
}
This works as expected and I catch the exception in the first method listed, I can access the status 503 and can see the message, however the message property of the exception always comes back in this format:
Server error: `POST http://docker.../search-organisations` resulted in a `503 Service Unavailable` response:
{"message":"The Experian Service is currently unavailable, please try again at 0600 GMT"}
It seems as though my supplied custom message has been concatenated with the standard Laravel Exception message (which I dont want). How can I make sure my message only contains what I supplied in my custom exception?
You could have your Exception implement Illuminate\Contracts\Support\Responsable and define the toResponse method to return that response. When you only have the render method the framework is still potentially going to do things to prepare the response. If it is Responsable it calls toResponse on it and returns that directly.
This causes a raw response from toResponse of your Exception to be returned without passing through any other parts of the Handler to be prepared in any way.
Maybe:
return Response::json(array(
'code' => 404,
'message' => $message
), 404);

How can I make Symfony2 ignore Guzzle Client bad response exception in my custom controller?

function order_confirmationAction($order,$token) {
$client = new \GuzzleHttp\Client();
$answer = $client->post("http://www.fullcommerce.com/rest/public/Qtyresponse",
array('body' => $order)
);
$answer = json_decode($answer);
if ($answer->status=="ACK") {
return $this->render('AcmeDapiBundle:Orders:ack.html.twig', array(
'message' => $answer->message,
));
} else throw new \Symfony\Component\HttpKernel\Exception\HttpException(500, $answer->message);
}
If $client->post() response status code is an "Error 500" Symfony stops the script execution and throw new exception before the json decoding.
How can I force Symfony to ignore $client->post() bad response and execute till the last if statement?
$client = new \GuzzleHttp\Client();
try {
$answer = $client->post("http://www.fullcommerce.com/rest/public/Qtyresponse",
array('body' => $serialized_order)
);
}
catch (\GuzzleHttp\Exception\ServerException $e) {
if ($e->hasResponse()) {
$m = $e->getResponse()->json();
throw new \Symfony\Component\HttpKernel\Exception\HttpException(500, $m['result']['message']);
}
}
I solved like this. In that way I can access to responses of remote server even if it returns an error 500 code.
Per Guzzle documentation:
Guzzle throws exceptions for errors that occur during a transfer.
Specifically, if the API responds with a 500 HTTP error, you shouldn't expect its content to be JSON, and you don't want to parse it, so you're better off re-throwing an exception from there already (or informing the user that something went wrong). I would suggest trying this out:
function order_confirmationAction($order, $token) {
$client = new \GuzzleHttp\Client();
try {
$answer = $client->post("http://www.fullcommerce.com/rest/public/Qtyresponse",
array('body' => $order)
);
}
catch (Exception $e) {
throw new \Symfony\Component\HttpKernel\Exception\HttpException(500, $e->getMessage());
}
$answer = json_decode($answer);
if ($answer->status=="ACK") {
return $this->render('AcmeDapiBundle:Orders:ack.html.twig', array(
'message' => $answer->message,
));
} else {
throw new \Symfony\Component\HttpKernel\Exception\HttpException(500, $answer->message);
}
}
It is probably also a good idea to check for errors when JSON-decoding the response, because there could be surprises in the content you're getting (eg. wrong format, missing or unexpected fields or values, etc.).

Slim Framewrok Exception handling

Am new to Slim framework and struggling to set up exception handling in slim, my requirement is to redirect to an error page when something unexpected happens in my code.
Tried this code
$smartView= new \Slim\Views\Smarty();
$app = new \Slim\Slim(array(
'debug' => false,
'view' => $smartView,
'templates.path' => '../templates/',
));
$app->error(function ( Exception $e ) use ($app) {
echo "my exception print here : " . $e;
});
in my index.php file, but slim slim still calling its default exception handler.
This is my router call
$app->get('/game', function () use ($app) {
try{
$facebook = new Facebook(array(
'appId' => appid,
'secret' =>appsecret,
'cookie' => true,
'allowSignedRequest' => true
));
$oStuff = new models\User ();
$oStuff->fbLogin($facebook); // To get User details and game select
}
catch (\Exception $e) {
//echo 'Caught exception: ', $e->getMessage(), "\n";
echo $e;
echo "catch exception";
}
});
this is my function having some errors
public function fbLogin($facebook)
{
$app = \Slim\Slim::getInstance();
$user = $facebook->getUser() // here is syntax error so i need to get it in my exception
}
Please help me to solve this issue, thanks in advance
If you are catching yourself an Exception like you do with you catch statement you won't let Slim handle the Exception for you so you will never enter your custom error method.
You can see official statement about error handling here and also check the code source here at line 1405.
So you have 2 choices here :
1) not try/catch your exception and let all exceptions be handled by Slim Framework
2) try/catch and throw a new Exception in your catch ... (not sure if its very useful)
Also consider the debug flag when bootstrapping the app, if true you will have a complete stacktrace of your exception, if false you need to display something nice to user in your "error" method.
You also can write your own log write so you will log Exception by yourself. More infos here

How do I handle multiple SOAP Faults during php Soap Client request?

I am interested in making a soap call via php’s soapClient to a web service to get the water level from a monitoring station. I want to handle two soapfaults that have occured during the execution. The first fault is as follows :
SoapFault exception: [soapenv:Server.userException] java.rmi.RemoteException: We are sorry, but no data is available from this station at this time in C:\xampp\htdocs\NOAA\LogWriter.php:214 Stack trace: #0 C:\xampp\htdocs\NOAA\LogWriter.php(214): SoapClient->__soapCall('getWaterLevelRa...', Array, Array) #1 C:\xampp\htdocs\NOAA\LogWriter.php(188): getLevel('8531680', '20120726 15:19') #2 {main}
This error is expected to occur several times during the script if the data for a certain time is not available. I need to catch this fault in order to tell the script to try again with a new time. I used a catch block to do so.
I also need to catch a second fault that occurs if the webservice is not loading the wsdl file or the server is timedout. To test for this have gave my script a faultly location to generate the same error I had received previously and it is as follows:
Fatal error: Uncaught SoapFault exception: [WSDL] SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://opendap.co-ops.nos.noaa.gov/axis/services/WaterLevelRawOneMin?wsdl' : Extra content at the end of the document in C:\xampp\htdocs\NOAA\LogWriter.php:210 Stack trace: #0 C:\xampp\htdocs\NOAA\LogWriter.php(210): SoapClient->SoapClient('http://opendap....', Array) #1 C:\xampp\htdocs\NOAA\LogWriter.php(171): getLevel('8531680', '20120726 12:35') #2 {main} thrown in C:\xampp\htdocs\NOAA\LogWriter.php on line 210
The second error remains uncaught and terminates my script. However I need to catch it and display a message.
I have posted my php function that makes the soap call below.
Could anyone give me any ideas on how to do this?
function getLevel($id, $date) {
$client = new SoapClient("http://opendap.co-ops.nos.noaa.gov/axis/services/WaterLevelRawOneMin?wsdl", array('trace' => false));
$Parameters = array("stationId" => $id, "beginDate" => $date, "endDate" => $date, "datum" => "MLLW",
"unit" => 1, "timeZone" => 1);
try {
return $client->__soapCall(
"getWaterLevelRawOneMin", array('Parameters' => $Parameters),
array('location' => "http://opendap.co-ops.nos.noaa.gov/axis/services/WaterLevelRawOneMin")
);
} catch (SoapFault $e) {
if (
$e->faultcode == "soapenv:Server.userException"
and $e->faultstring == "java.rmi.RemoteException: We are sorry, but no data is available from this station at this time"
) {
return "FAULT";
} else {
echo "Could not connect to the server";
}
} // end of catch blocK
}// end of function
Exception regarding broken WSDL can occur only when you call SoapClient::constructor so
try {
$client= new SoapClient($wsdlUrl ,array('trace'=>false));
}catch(Exception $e) {
// your loging regarding this case
}
SoapFault exception can occur when you make a webservice all so:
try {
$client= new SoapClient($wsdlUrl ,array('trace'=>false));
try {
return $client->_call('....');
} catch (SoapFault $sp) {
//your logic rearding soap fault
}
}catch(Exception $e) {
// your loging regarding this case
}
return false;

PHP - how can I mute/replace this Exception handler?

I'm using the Facebook PHP API, and around 1 time in 40 it dumps this exception on my webapp:
Uncaught CurlException: 56: SSL read:
error:00000000:lib(0):func(0):reason(0),
errno 104 thrown in ... on line 638
I'm not looking for a solution to what's causing the exception (already working on that), but for now I'd like to change it from dumping the exception on the page to either telling the user to refresh the page or refreshing the page automatically.
The exception is being thrown in this file: https://github.com/facebook/php-sdk/blob/master/src/facebook.php
This is the code I'd like to temporarily change to a refresh / refresh instruction:
if (curl_errno($ch) == 60) { // CURLE_SSL_CACERT
self::errorLog('Invalid or no certificate authority found, using bundled information');
curl_setopt($ch, CURLOPT_CAINFO,
dirname(__FILE__) . '/fb_ca_chain_bundle.crt');
$result = curl_exec($ch);
}
if ($result === false) {
$e = new FacebookApiException(array(
'error_code' => curl_errno($ch),
'error' => array(
'message' => curl_error($ch),
'type' => 'CurlException',
),
));
curl_close($ch);
throw $e;
}
You could use TRY .. CATCH to catch CurlException, or FacebookApiException there.
Or use set_exception_handler to catch any uncaught exception.
As strauberry said, you can stop throwing the exception. If the exception needs to be throw there, you can put the code that call this inside a try-catch and deal with the exception as you want.
Another option is to use the function set_exception_handler. This function will be called when an exception is thrown but nothing catch it.
You throw the Exception $e in the last line which causes the dumping. Instead you could do something like
echo "ERROR: " . $e->getMessage();

Categories