I am using Slim to code a REST API, I have come upon a situation where I need to check if the date time entered by user is valid and thus came up with this code
$app->post('/test', function() use($app)
{
verifyRequiredParams(array('d_string'));
$response = array();
$d_string = $app->request->post('d_string');
try {
$datetime = datetime::createfromformat('d M Y H:i:s', $d_string);
$output = $datetime->format('d-M-Y H:i:s');
}
catch (Exception $e) {
$response["error"] = true;
$response["message"] = $e->getMessage();
echoRespnse(400,$response);
}
$response["error"] = false;
$response["message"] = "Converted Date";
$response['output'] = $output;
echoRespnse(200,$response);
});
It works fine when I enter a valid date time string like 11-Dec-2015 12:18 but if just for testing purpose I enter some random string, it gives 500 internal error instead of giving me any exception.
Why is it ignoring the try catch block???
Error Info
PHP Fatal error: Call to a member function format() on a non-object
DateTime::createFromFormat will not throw an exception if the provided time string is invalid, but will return a boolean false.
So you don't really need a try/catch block to accomplish this:
$datetime = \DateTime::createFromFormat('d M Y H:i:s', $d_string);
if (false === $datetime) {
// send your 400 response and exit
}
$output = $datetime->format('d-M-Y H:i:s');
// the rest of the code
If you really want to keep your try/catch block for various reasons, you can throw an exception yourself and catch it locally:
try {
$datetime = \DateTime::createFromFormat('d M Y H:i:s', $d_string);
if (false === $datetime) {
throw new \Exception('Invalid date.');
}
$output = $datetime->format('d-M-Y H:i:s');
} catch (\Exception $e) {
$response["error"] = true;
$response["message"] = $e->getMessage();
echoRespnse(400,$response);
}
But I don't see a really good reason to throw an exception just to catch it locally in this situation, so I would go with first solution.
If you want to show more detailed error messages, you can use DateTime::getLastErrors method.
Related
I've created a REST API base on this tutorial - note that I am a newbie in php and REST...
Now, I am stuck when calling a POST request. The main return function is as follows:
// Requests from the same server don't have a HTTP_ORIGIN header
if (!array_key_exists('HTTP_ORIGIN', $_SERVER)) {
$_SERVER['HTTP_ORIGIN'] = $_SERVER['SERVER_NAME'];
}
try {
$API = new MyAPI($_REQUEST['request'], $_SERVER['HTTP_ORIGIN']);
$res = $API->processAPI();
echo $res; // contains my json as expected
return $res; // always empty string
} catch (Exception $e) {
echo "Exception: " . json_encode(Array('error' => $e->getMessage()));
}
EDIT
I've just tried something even simpler in the API caller method, namely following:
try {
$res = json_encode(Array('test' => "my message"));
// comment out one or the other to check output...
//echo $res;
return $res;
} catch (Exception $e) {
echo "Exception: " . json_encode(Array('error' => $e->getMessage()));
}
Result with echo is (the way I get responese is below... exact response is between # characters):
#{"test":"my message"}#
Result with return is
##
EDIT 2
Here is how I call the API from C#:
using (HttpClient client = new HttpClient()) {
JObject jo = new JObject();
jo.Add("usr", "username");
jo.Add("pwd", "password");
Uri url = new Uri(string.Format("{0}/{1}", RestUrl, "login"));
StringContent content = new StringContent(jo.ToString(), Encoding.UTF8, "application/json");
HttpResponseMessage response = await client.PostAsync(url, content);
bool isOk = response.StatusCode == System.Net.HttpStatusCode.OK;
// this is where I get the result from...
var res = response.Content.ReadAsStringAsync().Result;
}
I really don't understand this - could someone please explain in non-php expert terms??
I have a SoapClient that is falling sometimes.
// send request
$client = new SoapClient("http://XXXXXXXXX.org/NowPlaying.asmx?WSDL");
$result = $client->GetNowPlaying();
// get array of items
$arr = $result->GetNowPlayingResult->PlayerItem;
In those times I would like to show something insted of the Error Message. I have done many if/else statements but anything work.
Can you help me?
Have you tried a try/catch?
try {
// send request
$client = new SoapClient("http://XXXXXXXXX.org/NowPlaying.asmx?WSDL");
$result = $client->GetNowPlaying();
// get array of items
$arr = $result->GetNowPlayingResult->PlayerItem;
} catch (Exception $e) {
echo 'Sorry, there was a problem!<br><br>';
echo 'Caught exception: ', $e->getMessage(), "\n";
}
I believe Cloudant has recently changed some of their code. Recently, if you do a storedoc operation, in a try/catch statement. Cloudant will return an 'error' to the framework:
Uncaught exception 'couchException' with message 'Continue
Of course you can handle it in the catch statement, but it should really be coming back as 'successful' in the Try statement of the PHP-on-Couch library.
Anyone come across this or know how to handle it? The biggest issues is that you cannot grab the ID and Rev in the catch statement because it's coming up as an error:
try { // does not return here, goes to catch
$response = $client->storeDoc($doc);
$response_json['status'] = 'success';
$response_json['id'] = $response->id;
$response_json['rev'] = $response->rev;
} catch (Exception $e) { // even though the doc is successfully storing
// check for accepted BEG
$error = '';
$error = $e->getMessage();
$err_pos = strpos($error,"Accepted");
$err_pos_2 = strpos($error,"Continue");
if($err_pos !== false OR $err_pos_2 !== false){ // success
$response_json['status'] = 'success';
$response_json['id'] = $response->id; // returns null
$response_json['rev'] = $response->rev; // returns null
} else { // truely an error
$response_json['status'] = 'fail';
$response_json['message'] = $e->getMessage();
$response_json['code'] = $e->getCode();
}
// check for accepted END
}
I tested in both CouchDB and Cloudant and the behavior is the same. This is what I believe is happening. When you create a new couchDocument:
$doc = new couchDocument($client);
By default the document is set to autocommit. You can see this in couchDocument.php:
function __construct(couchClient $client) {
$this->__couch_data = new stdClass();
$this->__couch_data->client = $client;
$this->__couch_data->fields = new stdClass();
$this->__couch_data->autocommit = true;
}
As soon as you set a property on the document:
$doc->set( array('name'=>'Smith','firstname'=>'John') );
storeDoc is immediately called. You are then trying to call storeDoc a second time and couchDB returns an error.
There are 2 ways to fix this:
Turn off autocommit:
$doc = new couchDocument($client);
$doc->setAutocommit(false);
$doc->set( array('name'=>'Smith','firstname'=>'John') );
try {
$response = $client->storeDoc($doc);
$response_json['status'] = 'success';
$response_json['id'] = $response->id;
$response_json['rev'] = $response->rev;
Keep autocommit on and get the id and rev from the $doc after you set a property:
$doc = new couchDocument($client);
try {
$doc->set( array('name'=>'Smith','firstname'=>'John') );
$response_json['status'] = 'success';
$response_json['id'] = $doc->_id;
$response_json['rev'] = $doc->_rev;
I am trying to update database.
I have set up the webhook in stripe in test mode and send a "invoice.payment_succeeded" test webhook to file.but it shows response "none" in stripe output.
What have i done wrong, here is the webhook file, please someone help me, i am very stuck at this. any help will be appreciate...
<?php
include '../admin/include/functions.php';
require_once('Stripe/lib/Stripe.php');
require_once 'stripe_secret.php';
// Retrieve the request's body and parse it as JSON
$input = #file_get_contents("php://input");
$event_json = json_decode($input);
$event_id = $event_json->id;
if(isset($event_json->id)) {
try {
Stripe::setApiKey($stripe['secretkey']);
$event = Stripe_Event::retrieve($event_id);
var_dump($event);
$invoice = $event->data->object;
if($event->type == 'invoice.payment_succeeded') {
$customer = Stripe_Customer::retrieve($invoice->customer);
$email = $customer->email;
$customerid = $customer->id;
/*$amount = $invoice->amount / 100;*/
$expiry = $invoice->period->end;
$expiredate = date('Y-d-m', $expiry);
$userup = $obj->run_query("UPDATE users SET Expiry_Date = '$expiredate' WHERE user_stripe_id = '$customerid' ");
if ($userup) {
echo "User Date extended";
}
// send a invoice notice email here
}
if($event->type == 'invoice.payment_failed') {
$obj->run_query("UPDATE users SET Status = '0' WHERE user_stripe_id = '$customerid' ");
echo "User membership expired";
}
}
catch(Stripe_CardError $e) {
}
catch (Stripe_InvalidRequestError $e) {
// Invalid parameters were supplied to Stripe's API
} catch (Stripe_AuthenticationError $e) {
// Authentication with Stripe's API failed
// (maybe you changed API keys recently)
} catch (Stripe_ApiConnectionError $e) {
// Network communication with Stripe failed
} catch (Stripe_Error $e) {
// Display a very generic error to the user, and maybe send
// yourself an email
} catch (Exception $e) {
// Something else happened, completely unrelated to Stripe
}
}
http_response_code(200);
?>
The test webhooks from the test webhook button sends a webhook with the right format but all the values are null / zero / etc. Thus your line that does $obj->run_query("UPDATE users SET Expiry_Date = '$expiredate' WHERE user_stripe_id = '$customerid' "); will return a falsey result. This means you don't echo anything and just send back an empty 200 response.
I am calling some web services, using SoapClient. I am looking for a mechanism which will help me to display some errors to user, whenever web services goes offline or down.
As I have to wait for some time(15 sec) before displaying any errors to user. I am adding connection_timeout in SoapClient like this, for timeout.
$this->client = new SoapClient($clienturl,array('trace' => 1,
'exceptions'=> 1,
'connection_timeout'=> 15)); //$clienturl is webservice url
Also in top section of page, I have added this line,
ini_set("default_socket_timeout", 15); // 15 seconds
After specific timeout interval I am getting different SOAP-ERROR like this,
SOAP-ERROR: Parsing WSDL: Couldn't load from $clienturl
So I am looking for an error handler which will handle these SOAP-ERROR so as to display those in human-readable format to user like "Server is down, Try again after some time." Or Is there any way to handle timeout errors?
You can put it in a try/catch
try {
$time_start = microtime(true);
$this->client = new SoapClient($clienturl,array('trace' => 1,
'exceptions'=> 1,
'connection_timeout'=> 15
));
} catch (Exception $e) {
$time_request = (microtime(true)-$time_start);
if(ini_get('default_socket_timeout') < $time_request) {
//Timeout error!
} else {
//other error
//$error = $e->getMessage();
}
}
This is what I am using for soapClien connection in php
set_error_handler('error_handler');
function connectSoapClient($soap_client){
while(true){
if($soap_client['soap_url'] == ''){
trigger_error("Soap url not found",E_USER_ERROR);
sleep(60);
continue;
}
try{
$client = #new SoapClient($soap_client['soap_url'],array("trace" => 1,"exceptions" => true));
}
catch(Exception $e){
trigger_error("Error occured while connection soap client<br />".$e->getMessage(),E_USER_ERROR);
sleep(60);
continue;
}
if($client){
break;
}
}
return $client;
}
function error_handler($errno, $errstr, $errfile, $errline){
if($errno == E_USER_ERROR){
$error_time = date("d-m-Y H:i:s");
$errstr .= "\n
############################### Error #########################################\n
Error No: $errno
Error File: $errfile
Line No: $errline
Error Time : $error_time \n
##############################################################################
";
mail($notify_to,$subject,$errstr);
}
}