PHP exception handling on DateTime object - php

Does anybody know why this function, when passed an invalid date (e.g. timestamp) to it, still throws an error despite the try-catch?
function getAge($date){
try {
$dobObject = new DateTime($date);
$nowObject = new DateTime();
$diff = $dobObject->diff($nowObject);
}
catch (Exception $e) {
echo 'Error: ', $e->getMessage();
}
return $diff->y;
}
Error:
Fatal error: Uncaught exception 'Exception' with message 'DateTime::_construct() [datetime.--construct]: Failed to parse time string (422926860) at position 7 (6): Unexpected character' in ... .php:4 Stack trace: #0 ... .php(4): DateTime->_construct('422926860') #1 ... .php(424): getAge('422926860') #2 {main} thrown in/... .php on line 4
Thank you very much in advance!

Chris, you cannot catch fatal errors, at very least you shouldn't.
Quoting keparo:
PHP won't provide you with any conventional means for catching fatal errors because they really shouldn't be caught. That is to say, you should not attempt to recover from a fatal error. String matching an output buffer is definitely ill-advised.
If you simply have no other way, take a look at this post for more info and possible how-tos.
Try this:
function isDateValid($str) {
if (!is_string($str)) {
return false;
}
$stamp = strtotime($str);
if (!is_numeric($stamp)) {
return false;
}
if ( checkdate(date('m', $stamp), date('d', $stamp), date('Y', $stamp)) ) {
return true;
}
return false;
}
And then :
if isDateValid( $yourString ) {
$date = new DateTime($yourString);
}

Related

Show Exception message when passing invalid argument type

I have a function
<?php
public function setStatusToReadyToShip(array $order_item_ids, $delivery_type, $shipping_provider = '', $tracking_number = '')
{
//code
}
Now I want the caller to call this method by providing $order_item_ids in array format.
One way i could do is to check is_array($order_item_ids) and send the error to the caller. But i am to utilize Type Hinting. How would i send the user the error response when using type hinting. As currently it crashes the application and says
exception 'ErrorException' with message 'Argument 1 passed to Class::SetStatusToReadyToShip() must be of the type array, integer given
I am not familiar with the try catch stuff that much. I tried placing try-catch inside this function so that it does not crash the application but the same output received.
Thanks
It is Catchable fatal error with constant E_RECOVERABLE_ERROR
There are 2 methods to solve this problem (at least two).
Create your own exception handler and set it as main error handler.
Make type validation in your function, and throw exception from it:
function setStatusToReadyToShip($order_item_ids, $delivery_type, $shipping_provider = '', $tracking_number = '')
{
if (!is_array($order_item_ids)) {
throw new InvalidArgumentException('First parameter of function '.__FUNCTION__.' must be array');
}
// your code
}
and than catch it
try {
setStatusToReadyToShip(5, 6);
} catch(InvalidArgumentException $e) {
var_dump($e->getMessage());
}
<?php
class YourClass {
public static function _init() {
set_error_handler('YourClass::_typeHintHandler');
}
public static function _typeHintHandler($errorCode, $errorMessage) {
throw new InvalidArgumentException($errorMessage);
}
public function setStatusToReadyToShip(array $order_item_ids, $delivery_type, $shipping_provider = '', $tracking_number = '')
{
}
}
YourClass::_init();
$yo = new YourClass();
try {
$yo->setStatusToReadyToShip("test");
}catch(Exception $e) {
print $e->getMessage();
}

XML Exception in PHP not being caught

My code snippet is below - as you can see, I have a try-catch block, but inspite of this, I still get an uncaught exception that terminates the entire application. What am I missing?
try {
$cakeXml = simplexml_load_string($xml);
$parseSuccess = $cakeXml->xpath('//ParseSuccess');
} catch (Exception $ex) {
$response['parseSuccess'] = false;
$response['errors']['ParseError'] = 'An unknown error occurred while trying to parse the file. Please try again';
return $response;
}
2014-12-16 22:45:12 Error: Fatal Error (1): Call to a member function xpath() on a non-object
2014-12-16 22:45:12 Error: [FatalErrorException] Call to a member function xpath() on a non-object
If you read the error message more-carefully, you will see that it is not dieing on an Exception, but on a Fatal Error. A try/catch statement cannot catch a fatal error in PHP, as there is no way to recover from a fatal error.
As for solving this issue, your error is telling you $cakeXml is a non-object. One solution would be to do something like this.
try {
$cakeXml = simplexml_load_string($xml);
if (!is_object($cakeXml)) {
throw new Exception('simplexml_load_string returned non-object');
}
$parseSuccess = $cakeXml->xpath('//ParseSuccess');
} catch (Exception $ex) {
$response['parseSuccess'] = false;
$response['errors']['ParseError'] = 'An unknown error occurred while trying to parse the file. Please try again';
return $response;
}
DOMXPath methods i.e. xpath or evaluate does not throw exceptions. Hence, you will need to explicitly validate and throw the exception.
See below code snippet:
$xml_1= "";
try {
$cakeXml = simplexml_load_string($xml_1);
if ( !is_object($cakeXml) ) {
throw new Exception(sprintf('Not an object (Object: %s)', var_export($cakeXml, true)));
} else {
$parseSuccess = $cakeXml->xpath('//pages');
print('<pre>');print_r($parseSuccess);
}
} catch (Exception $ex) {
echo 'Caught exception: ', $ex->getMessage(), "\n";
}

Basic PHP / SOAP error, can't debug

I'm currently having a really frustrating time with some really simple SOAP / PHP at the moment. I've spent about a week trying EVERYTHING I can think of, on multiple different servers with different versions of PHP and they all still throw the same error. Here's the code:
function test() {
$client = new SoapClient('http://xxx', array("login" => "sandbox", "password" => "password"));
print_r($client->__getFunctions());
$ap_param = array();
// it dies here. CheckServiceAvailable is a valid function returned in __getFunctions()
$result = $client->__soapcall('CheckServiceAvailable', $ap_param);
if (is_soap_fault($result)) {
trigger_error("SOAP Fault: (faultcode: {$result->faultcode}, faultstring: {$result->faultstring})", E_USER_ERROR);
}
}
It faults before the error catching can capture anything. Apache logs show the same fault as below:
Fatal error: Uncaught SoapFault exception: [s:Processing error] in C:\soap.php:13 Stack trace: #0 C:\soap.php(13): SoapClient->__soapCall('CheckServiceAva...', Array) #1 C:\soap.php(23): test() #2 {main} thrown in C:\soap.php on line 13
Without being able to catch the fault I'm totally stuck as to what to do. I don't really want to try nusoap.
Any ideas?
use:
try
{
$result = $client->__soapcall('CheckServiceAvailable', $ap_param);
}
catch (SoapFault $e)
{
echo "Cannot call method CheckServiceAvailable: {$e->getMessage()}";
}

DateTime::__construct(): Failed to parse time string

I configured redmine with my website for handling exceptions. Now when website is on production environment I have strange exception.
StackTrace:
An exception has been thrown during the rendering of a template ("DateTime::__construct(): Failed to parse time string (date) at position 0 (d): The timezone could not be found in the database") in "ToFrontendBundle:Page:cruise-periodic.html.twig" at line 8.
#95: To\FrontendBundle\Controller\PageController->cruisePreviewAction(8, way, date)
#106: Symfony\Bundle\FrameworkBundle\Controller\Controller->render("ToFrontendBundle:Page:cruise-periodic.html.twig", array)
#112: Symfony\Bundle\TwigBundle\TwigEngine->renderResponse("ToFrontendBundle:Page:cruise-periodic.html.twig", array, NULL)
#83: Symfony\Bundle\TwigBundle\TwigEngine->render("ToFrontendBundle:Page:cruise-periodic.html.twig", array)
#53: Symfony\Bridge\Twig\TwigEngine->render("ToFrontendBundle:Page:cruise-periodic.html.twig", array)
#4423: Twig_Template->render(array)
#4416: Twig_Template->display(array)
#4446: Twig_Template->displayWithErrorHandling(array, array)
But, I handle exception like:
try {
$date = new \DateTime($date);
$date = $date->format('j-n-Y');
} catch (\Exception $e) {
$date = new \DateTime("now");
$date = $date->format('j-n-Y');
$first = false;
}
My cruise-periodic.html.twig:
<span class="padding-left-10 light-green text-14 selected-date" data-date="{{ date | date('j/n/Y') }}">{{ date | toDateFormat }}</span>
What I do wrong?
EDIT
Someone is causing the exception but i cannot tell how. I cannot manually test this situation. String variables "date" and "way" are replaced in js. Possibly that someone is finding the dom href and invoking it blindly. Could it be robots or bots ? How I can prevent them from accessing this action?
I meant try to execute next code:
try {
$date = new \DateTime('2010-10-10');
$date = $date->format('j-n-Y');
} catch (\Exception $e) {
$date = new \DateTime("now");
$date = $date->format('j-n-Y');
$first = false;
}
Is it also catch this exception or it work?

How to check for a failed DateTime in PHP?

When the following gets bad data PHP aborts.
PHP Fatal error: Uncaught exception 'Exception' with message 'DateTime::__construct(): Failed to parse time string (980671) at position 4 (7): Unexpected character'
How can I catch this if the data is bad to take other action so the PHP problem doesn't fail?
$date = new DateTime($TRANSACTION_DATE_MMDDYY_raw);
Use try and catch
try {
$date = new DateTime($date);
} catch(Exception $e) {
echo "Invalid date... {$e->getMessage()}";
}
As #Rob W already said, you gotta catch that exception.
But what could cause that exception is inaproppriate datetime format.
To solve this, you could do instead:
try {
$dt = DateTime::createFromFormat("MMDDYY", $TRANSACTION_DATE_MMDDYY_raw) ;
} catch(Exception $e){
echo "Something went wrong: {$e->getMessage()} " ;
}
More about it: http://www.php.net/manual/en/datetime.createfromformat.php

Categories