I want to receive the error message in php before it gets executed. Basicly what i mean is that if I would have a bad code:
// This code is incorrect, I want to receive the error before it gets handled!
$some_var = new this_class_is_not_made;
Now that class does not exist, so it would be handles by the default error handler in php. But I want to disable the normal error handler and create my own.
Another example:
somefunction( string some_var ); // some_var misses the variable prefix. ( $ )
Example error message:
Fatal error: function 'some_var' is not defined in line: $x!
And this error would be: somefunction( string some_var );
But how would I receive the messages but also disable the normal error system?
EDIT: Making the error system execute a user-defined function
// I would want the error system to execute a function like this:
function(string $errorMessage, int $error_code){
if($error_code < 253){ return "Fatal error"; }
if($error_code < 528 && $error_code > 253){ return "Warning"; }
}
Answer found: By: ShiraNai7
try
{
// Code that may throw an Exception or Error.
}
catch (Throwable $t)
{
// Executed only in PHP 7, will not match in PHP 5
}
catch (Exception $e)
{
// Executed only in PHP 5, will not be reached in PHP 7
}
In PHP 7.0.0 or newer the code will throw Error exception if this_class_is_not_made doesn't exist.
try {
$some_var = new this_class_is_not_made;
} catch (Error $e) {
echo $e->getMessage();
}
Note that that this will also catch any other Error exceptions in case this_class_is_not_made does exist and causes some other error along the way.
In PHP versions prior to 7.0.0 you're out of luck - fatal errors always terminate the main script.
It might be a better idea to use class_exists() instead:
if (class_exists('this_class_is_not_made')) {
$some_var = new this_class_is_not_made;
}
This works in all PHP versions that support classes.
Related
This isn't necessarily a CakePHP problem but I'm using CakePHP 2.8 and PHP 5.6.
I have a function named save_order which calls another function named changePathItemOrder using a try/catch. That function calls another function named _reorderItemsOnPath, which in turn calls another function named _moveItemsForwards. It's a few levels deep, so here's a little graphic to keep us all on track:
Cascade of Functions
The try/catch in sort_order is:
$data['status'] = 'success';
try {
$this->PathRepository->deletePathItemFromPath($milestoneId, $pathId, $accountId);
} catch(Exception $e) {
debug('Caught error');
$data['status'] = 'error';
$data['message'] = $e->getMessage();
}
$this->set(compact('data'));
$this->render('/Elements/json');
If an error occurs in _moveItemsForwards, I throw an error like:
throw new InternalErrorException('Invalid path item ID: ' . $pathItemId);
The problem is that the try/catch in sort_order doesn't catch the error thrown by _moveItemsForwards. The catch doesn't even execute because the debug doesn't show up in the resulting error message. I just get the following Error :-
500 Error! Something broke!
Return to the homepage
Invalid path item ID: 76
What's the best way to handle this error and get the error message back to the save_order function?
I am new to php, i am from java background, i am wondering why php doesn't goes directly when exception occured in try block without throwing that exception manually.
e.g.
<?php
//create function with an exception
function checkNum($number) {
if($number/0) {
throw new Exception("Value must be 1 or below");
}
return true;
}
//trigger exception in a "try" block
try {
checkNum(2);
//If the exception is thrown, this text will not be shown
echo 'If you see this, the number is 1 or below';
}
//catch exception
catch(Exception $e) {
echo 'Message: ' .$e->getMessage();
}
?>
in above example in if condition the divide by zero exception is occured and then it will directly go to the catch block instead it goes to inside if.why?
The code you posted doesn't do what you say it does.
When you execute:
if ($number/0)
the division by zero prints a warning, and then returns false. Since the value is not truthy, it doesn't go into the if block, so it doesn't execute the throw statement. The function then returns true. Since the exception wasn't thrown, the statement after the call to checkNum(2) is executed, so it prints the message.
When I run your code, I get the output:
Warning: Division by zero in scriptname.php on line 5
If you see this, the number is 1 or below
PHP doesn't use exceptions for its built-in error checks. It simply displays or logs the error, and if it's a fatal error it stops the script.
This has been changed in PHP 7, though. It now reports errors by throwing an exception of type Error. This isn't a subclass of Exception, so it won't be caught if you use catch (Exception $e), you'll need to use catch (Error $e). See Errors in PHP 7. So in PHP 7 you could write:
<?php
//create function with an exception
function checkNum($number) {
if($number/0) {
throw new Exception("Value must be 1 or below");
}
return true;
}
//trigger exception in a "try" block
try {
checkNum(2);
//If the exception is thrown, this text will not be shown
echo 'If you see this, the number is 1 or below';
}
//catch exception
catch(Error $e) {
echo 'Message: ' .$e->getMessage();
}
How do i catch (custom)exceptions (with custom exception handler) that i have thrown in custom shutdown function ? I am not using any framework.
Example:
register_shutdown_function( 'shutdownFunction');
set_exception_handler( 'exceptionHandler');
function exceptionHandler(Exception $exception)
{
// handle and log exception for later debugging...
}
function shutdownFunction()
{
// something is not going right...
if (someVariable != someValue)
throw new RuntimeException('blah...'); // WILL NOT be caught by exception handler
}
// somewhere else in the code...
throw new Exception('something...'); // WILL be caught by exception handler (but not in shutdown function)
The script is using exceptions to communicate that it encountered an error during execution ie. unexpected variable passed to function, database failed to insert row etc...
You simply cannot do this in php.
The register_shutdown_function callback is the last thing that happens in your PHP application. Trying to throw an exception in there will not do anything but invoke a standard php handler. There isn't much to be found on the web regarding these inner workings.
However, I created my own solution for directing it to a single function.
set_exception_handler and register_shutdown_functionare very different functions:
set_exception_handler receives a single argument Exception
register_shutdown_function receives no arguments by default
I've made it so that the set_exception_handler (which receives $exception as argument) sets a property which I can use in the register_shutdown_function.
$lastException = null;
set_exception_handler(function ($e) use (&$lastException) {
$lastException = $e;
});
register_shutdown_function(function() use(&$lastException) {
if($error = error_get_last()) {
$lastException = new \ErrorException($error['message'], $error['type'], 1, $error['file'], $error['line']);
}
if($lastException) {
if (APPLICATION_ENV === 'production') {
Sentry\captureException($lastException);
} else {
var_dump($lastException);
}
}
});
I have no clue if this is a good way to solve the issue, but it allowed me to catch require unexisting_phpfile1389.php errors (Fatal) and regular throw \Exception()s in the same function.
Trying to throw an exception inside the shutdown handler will result in the following exception (how ironic):
( ! ) Fatal error: Uncaught Error: Can only throw objects in
C:...\index.php on line 34
( ! ) Error: Can only throw objects in
C:...\index.php on line 34
You can just wrap the body of your shutdownFunction with
function shutdownFunction()
try {
...
} catch (\Exception $e) {
// do something
}
}
and you will catch all exceptions becase Exception is the base class for all of them
It's quite simple:
function exception_handler (Exception $e) {
if ($e instanceof DBException)
error_handler (['query' => $e->getQuery ()]); // Your actions with your custom Exception object
}
function error_handler ($error) {
if (isset ($error['query']))
echo $error['query'];
else
// Another errors
}
set_error_handler ('error_handler', E_ALL);
set_exception_handler ('exception_handler');
I am setting up Twilio and trying to send a simpe sms to my personal phone. but all i get is this error in title + this happens on Services/Twilio/Resource.php on line 127:
public function __toString() {
$out = array();
foreach ($this as $key => $value) {
if ($key !== "client" && $key !== "subresources") {
$out[$key] = (string)$value; <----------------HERE
}
}
return json_encode($out);
}
My code on controller look like this:
$client = new Services_Twilio($AccountSid, $AuthToken);
try {
foreach($listUsers as $user){
$sms = $client->account->sms_messages->create(
$phone, // From this number
$user['phone'], // To this number
$message
);
}
$data['results'] = "success";
$data['message'] = "Your message have been sent successfully";
echo json_encode($data);
} catch (Services_Twilio_RestException $e) {
$data['results'] = "error";
$data['message'] = $e->getMessage();
echo json_encode($data);
}
I am sitting for hours now, can't seem to figure out the problem. Maybe some one have used this Twilio and could give me a hint atleast where to look..
Whole error:
PHP Catchable fatal error: Object of class Services_Twilio_TinyHttp could not be converted to string in ../Services/Twilio/Resource.php on line 127, referer:
Errors are not Exceptions, they are not thrown and cannot be catched. Errors can be handled by error handlers registered with set_error_handler. Now, there are several fatal error types like E_ERROR or E_CORE_ERROR, which cannot be handled by any error handler; these errors are fatal and stop script execution, period (or full stop if you prefer ;)). But there's also an E_RECOVERABLE_ERROR, which is described as such:
Catchable fatal error. It indicates that a probably dangerous error occurred, but did not leave the Engine in an unstable state. If the error is not caught by a user defined handle (see also set_error_handler()), the application aborts as it was an E_ERROR.
http://www.php.net/manual/en/errorfunc.constants.php
So you could handle these errors with a custom error handler. You should mostly do that to possibly write custom error logs or send alert mails, but you should nonetheless terminate the script afterwards (though you are not forced to). It's just being described as a "catchable error", though it has nothing to do with try..catch.
The cause of the error in your case is that you're trying to cast an object to a string, but the object doesn't like that. You should look at the documentation for the class how the object wants to be treated and how you can get the data you want out of it. (string) does not work, plain and simple.
You should be able to convert any of the resources, eg $client->account, $message = $client->account->messages->get('MM123') to a string, by calling echo on it or similar.
It looks like somewhere you are trying to cast the http client ($client->http) to a string. The http client doesn't define a tostring method.
I'm calling a method that I know could cause an error and I'm trying to handle the error by wrapping the code in a try/catch statement...
class TestController extends Zend_Controller_Action
{
public function init()
{
// Anything here happens BEFORE the View has rendered
}
public function indexAction()
{
// Anything `echo`ed here is added to the end of the View
$model = new Application_Model_Testing('Mark', 31);
$this->view->sentence = $model->test();
$this->loadDataWhichCouldCauseError();
$this->loadView($model); // this method 'forwards' the Action onto another Controller
}
private function loadDataWhichCouldCauseError()
{
try {
$test = new Application_Model_NonExistent();
} catch (Exception $e) {
echo 'Handle the error';
}
}
private function loadView($model)
{
// Let's pretend we have loads of Models that require different Views
switch (get_class($model)) {
case 'Application_Model_Testing':
// Controller's have a `_forward` method to pass the Action onto another Controller
// The following line forwards to an `indexAction` within the `BlahController`
// It also passes some data onto the `BlahController`
$this->_forward('index', 'blah', null, array('data' => 'some data'));
break;
}
}
}
...but the problem I have is that the error isn't being handled. When viewing the application I get the following error...
( ! ) Fatal error: Class 'Application_Model_NonExistent' not found in /Library/WebServer/Documents/ZendTest/application/controllers/TestController.php on line 23
Can any one explain why this is happening and how I can get it to work?
Thanks
use
if (class_exists('Application_Model_NonExistent')) {
$test = new Application_Model_NonExistent;
} else {
echo 'class not found.';
}
like #prodigitalson said you can't catch that fatal error.
An error and an exception are not the same thing. Exceptions are thrown and meant to be caught, where errors are generally unrecoverable and triggered with http://www.php.net/manual/en/function.trigger-error.php
PHP: exceptions vs errors?
Can I try/catch a warning?
If you need to do some cleanup because of an error, you can use http://www.php.net/manual/en/function.set-error-handler.php
Thats not an exception, thats a FATAL error meaning you cant catch it like that. By definition a FATAL should not be recoverable.
Exception and Error are different things. There is an Exception class, which you are using and that $e is it's object.
You want to handle errors, check error handling in php-zend framework. But here, this is a Fatal error, you must rectify it, can not be handled.