Why exception handling does not work in PHP [duplicate] - php

This question already has answers here:
PHP, How to catch a division by zero?
(15 answers)
Closed 1 year ago.
I have this PHP code. Whenever y becomes zero, it shows a warning instead of catching the exception. Is there anything wrong with my code?
try
{
return($x % $y);
throw new Exception("Divide error..");
}
catch(Exception $e){
echo "Exception:".$e->getMessage();
}
I got this warning:
Warning: Division by zero in file.php
The catch block is not run. What am I doing wrong?

A warning is not an exception. Warnings cannot be caught with exception handling techniques. Your own exception is never thrown since you always return before.
You can suppress warnings using the # operator like #($x % $y), but what you should really do is make sure $y does not become 0.
I.e.:
if (!$y) {
return 0; // or null, or do something else
} else {
return $x % $y;
}

Yes, you are executing the return before the throw. Hence the throw is never executed and no exception is thrown nor caught.

this is how it should be done
$value;
try
{
$value = $x%$y;
}
catch(Exception $e){
throw new Exception("Divide error..");
echo "Exception:".$e->getMessage();
}
return $value
But since you are getting a warning if you want to hide the error and handle it discretely
You can use the # sign
$value = #$x%$y;
now you can test the value and see if it has the value it has

Related

Try catch not working in Laravel 5.6 when a number is divided by zero [duplicate]

This question already has answers here:
Can I try/catch a warning?
(13 answers)
Closed 3 years ago.
Try catch block can not prevent run time exception in my Laravel code.
I wrote following code to test the exception handling:
try{
$a=112/0;
}catch(Exception $e){
$a=99;
}
But it returns a Run time error. Please help me to solve the issue.
Try this:
try{
$a=112/0;
}catch(\Exception $e){
$a=99;
}
Notice the \ before Exception.
Update: As #Qirel suggests:
You can simply update your code to do it without try/catch:
if($d === 0){
$a = 99;
} else{
$a = 112/$d
}
Because you are using php7 you need to use Throwable to catch the exception like this:
try{
$a=112/0;
}catch(Exception $e){
// For php 5
$a=99;
} catch(\Throwable $e) {
// For php7
$a=99;
}

why does php doesn't go inside catch block without throwing an exception

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 to catch hex2bin() warning

Came across this today, not sure how to solve it.
I want to catch an E_WARNING level error issued by hex2bin().
I thought I might be able to use a try()catch() exception method but it did not work.
try {
$foo = hex2bin($bar);
}
catch (Exception $e) {
die('Custom message');
}
The standard E_WARNING that is issued is, of course:
Warning: hex2bin(): Input string must be hexadecimal string
In this particular situation I do not want to use the standard methods to disable errors, such as:
error_reporting(-1);
error_reporting(E_ALL);
ini_set("display_errors", 1);
Nor do I want to suppress the error using a #hex2bin method.
I actually want to have a custom error displayed, but I just do not seem to be able to find a way to catch when hex2bin throws an error.
You can check the input value to verify that it is hex before passing it to the hex2bin method.
if (ctype_xdigit($bar) && strlen($bar) % 2 == 0) {
$foo = hex2bin($bar);
} else {
//display error here
}
Per the documentation, hex2bin returns:
the binary representation of the given data or FALSE on failure.
That means you can do something like this if you want to use it in a try/catch block:
try {
$foo = #hex2bin($bar);
if(false === $foo) {
throw new Exception("Invalid hexedecimal value.");
}
} catch(Exception $e) {
echo $e;
}
Yes, hex2bin is suppressed. You can remove the # if you set error_reporting to suppress warnings.
Alternatively, you can check the type of $foo with ctype_xdigit() prior to using hex2bin().

Get error before they execute the error message function

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.

User friendly php try catch

Since a short period of time I'm working with Try Catch in PHP. Now, every time a new error is thrown you get a fatal error on the screen, this isn't really user friendly so I was wondering if there's a way to give the user a nice message like an echo instead of a fatal error.
This is the code I have now:
public static function forceNumber($int){
if(is_numeric($int)){
return $int;
} else {
throw new TypeEnforcerException($int.' must be a number');
}
}
public function setStatus($status) {
try {
$this->status = TypeEnforcer::forceInt($status);
} catch (TypeEnforcerException $e) {
throw new Exception($e->getMessage());
} catch (Exception $e) {
throw new Exception($e->getMessage());
}
}
This is best solved with a frontend controller that is able to catch all uncatched exceptions:
<?php
require('bootstrap.php');
try {
$controllerService->execute($request);
} catch (Exception $e) {
$controllerService->handleControllerException($e);
}
You can then write code to return the internal server error because an exception signals an exceptional case so it normally is an 500 internal server error. The user must not be interested what went wrong other than it just didn't work out and your program crashed.
If you throw exceptions to give validation notices you need to catch those in a different layer (and you're probably doing it wrong if you use exceptions for that).
Edit: For low-level functions, because PHP is loosely typed, if a function expects and int, cast to intDocs:
public static function forceNumber($int){
$int = (int) $int;
return $int;
}
this will actually force the integer. In case the cast is not possible to do (e.g. $int it totally incompatible) PHP will throw the exception for you.
The example is a bit akward because by the method's name you use it to validate some number and provide an error if not (here wrongly with an exception). Instead you should do some validation. If you expect wrong input, it's not an exceptional case when wrong input is provided, so I would not use exceptions for that.

Categories