Try/Catch block in PHP not catching Exception - php

I am trying to run this Example #1 from this page: http://php.net/manual/en/language.exceptions.php
<?php
function inverse($x) {
if (!$x) {
throw new Exception('Division by zero.');
}
return 1/$x;
}
try {
echo inverse(5) . "\n";
echo inverse(0) . "\n";
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
}
// Continue execution
echo "Hello World\n";
?>
However instead of the desired output I get:
0.2
Fatal error: Uncaught exception 'Exception' with message 'Division by zero.'
in xxx:
7 Stack trace: #0 xxx(14): inverse(0) #1 {main} thrown in xxx on line 7
The developer environment I am using is UniServer 3.5 with PHP 5.2.3

I just had this exact problem where it seemed like I had even copied the name of the exception and yet it didn't catch it. It turned out it was my stupid mistake but I thought I should post my case here in case there is someone else in the same situation.
I had my exception in my namespace called A and the script was in a namespace called B. The problem was that I had A\MyException which equals (in PHP) \B\A\MyException (because my script is in the namespace called B!). All I had to do to fix it was to add backslash (or whatever it's called) to the exception name so it would look like this: \A\MyException

Quite old question, yet...
I had this problem as well (and that's how I found this post) but just simple experiment allowed me to find the solution. Just try changing Exception to \Exception. Worked for me!
EDIT:
As sivann pointed in the comments, using namespace should do the same thing. So simply put use \Exception as Exception; before your class declaration.

Try to put catch(\Exception $e) instead of catch(Exception $e) . If you are using a code you don't know about very well, or - especially - if you are using a framework, it might override the default PHP Exception with one of its own, and therefore you might go to the wrong path and get the undesired result. If you just put \Exception , then you are sure you are catching the base PHP exception.

\Exception doesn't work for me but I found a solution.
I needed to replace:
try {
...
} catch(Exception $e){
...
}
by
try {
...
} catch(Throwable $e){
...
}.
For more information : https://trowski.com/2015/06/24/throwable-exceptions-and-errors-in-php7/

You can not use the typical try{} catch{} blocks in PHP as you could do in another language like C# (Csharp).
If you do this:
try{
//division by zero
$number = 5/0;
}
catch(Exception $ex){
echo 'Got it!';
}
You will not see the 'Got it!' message never. Why? It's just because PHP always needs an Exception to be "Thrown". You need to set your own error handler and throw an Exception with it.
See set_error_handler function: http://php.net/manual/es/function.set-error-handler.php

If you are using PHP 7, you may need Throwable instead of Exception

In my case, a weird situation occurred and catching Exception didn't work even when I had \Exception. Here is what to do to make sure that you never miss anything and always catch the error.
catch (\Exception $e) {
// do what you want to do on exception catching
} catch (\Throwable $e) {
// do what you want to do on exception catching
}
When you combine these two, you will never miss catching an Exception. Make sure to put the \ before Exception and Throwable. That's important.
Edit
An efficient way to catch them would be this
catch (\Exception|\Throwable $e) {
// do what you want
}
This will catch that without you having two separate catch blocks

My initial though is you have a typo in the name of the exception you are catching/throwing, but if your code is exactly the same I'm not sure exactly what is going on.
Try the following modification of the original script, and paste your results. It will help diagnose your issue a bit better.
<?php
//set up exception handler to report what we didn't catch
function exception_handler($exception) {
if($exception instanceof MyException) {
echo "you didn't catch a myexception instance\n";
} else if($exception instanceof Exception) {
echo "you didn't catch a exception instance\n";
} else {
echo "uncaught exception of type: ".gettype($exception)."\n";
}
echo "Uncaught exception: " , $exception->getMessage(), "\n";
}
//install the handler
set_exception_handler('exception_handler');
class MyException extends Exception {
}
function inverse($x) {
if (!$x) {
throw new MyException('Division by zero.');
}
else return 1/$x;
}
try {
echo inverse(5) . "\n";
echo inverse(0) . "\n";
} catch (MyException $e) {
echo 'Caught myexception: ', $e->getMessage(), "\n";
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
}
// Continue execution
echo 'Hello World';
?>

I had the same problem with following configurations,
PHP 5.2.14 (cli) (built: Aug 12 2010 17:32:30)
Copyright (c) 1997-2010 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2010 Zend Technologies
with eAccelerator v0.9.5.1, Copyright (c) 2004-2006 eAccelerator, by eAccelerator
The solution is to either disable eAccelerator or update it. I tried both and both of the fixes worked. The bug is reported here https://eaccelerator.net/ticket/242 (NB. firefox complains about their SSL cert) .
Now I am running try catch properly with following configurations,
PHP 5.2.4 (cli) (built: Oct 16 2007 09:13:35)
Copyright (c) 1997-2007 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies
with eAccelerator v0.9.6.1, Copyright (c) 2004-2010 eAccelerator, by eAccelerator

catch all exception in php
try
{
//place code
throw new Exception('foo');//eg
}
catch (\Throwable $e)
{
dd('for php 7');
} catch (\Exception $e)
{
dd('for php 5');
}
https://www.php.net/manual/en/language.exceptions.php

in Xdebug there is a setting:
xdebug.show_exception_trace = 1
This will force php to output exceptions even in a try catch block.
Turn this to 0

TLDR; make sure you have use Exception; on the top of both php files

Maybe try disabling certain 3rd party extensions you might have installed?
http://bugs.php.net/bug.php?id=41744

I am experiencing this as well. I read comment from Rowinson Gallego which state Exception must be thrown. So I modified my code from :
try
{
$number = 5/0; //or other exception
}
catch(Exception $e)
{
throw $e;
}
into :
try
{
$number = 5/0; //or other exception
}
catch(Exception $e)
{
throw new Exception($e->getMessage(),$e->getCode());
}
It works.

Again this old thread revisited...
I had not require_once'd the file containing my Exception subclass in the file with the try/catch block.
Somehow (maybe due to composer's autoload) this didn't result in a 'cannot be resolved to a type' error. And somehow my exception was being created with the expected namespace (in yet another file without the require_once). But it wasn't caught. My directory structure does not match the namespaces so autoload might have loaded the correct class in the file with the try/catch but under a different namespace.

Try to add a backslash before the class for example:
BEFORE
try {
if ($this->customerAuth->authenticate($customerId, $password)) {
$this->session->loginById($customerId);
}
} catch(Magento\Framework\Exception\State\UserLockedException $e) {
return $this->respondWithCode('login', 401);
} catch (Magento\Framework\Exception\InvalidEmailOrPasswordException $e) {
return $this->respondWithCode('login', 401);
}
AFTER
try {
if ($this->customerAuth->authenticate($customerId, $password)) {
$this->session->loginById($customerId);
}
} catch(\Magento\Framework\Exception\State\UserLockedException $e) {
return $this->respondWithCode('login', 401);
} catch (\Magento\Framework\Exception\InvalidEmailOrPasswordException $e) {
return $this->respondWithCode('login', 401);
}

Related

Can't catch exceptions in laravel

I have the following situation:
try {
DB::beginTransaction();
$task = new Task();
$task->setTracker("");
//thrown \Symfony\Component\Debug\Exception\FatalThrowableError
DB::commit();
}catch (\Exception $e){
DB::rollBack();
Log::error($e);
//throw $e;
}
I am not entering to the catch area.
Any idea why?
update
This is the error thrown:
[Symfony\Component\Debug\Exception\FatalThrowableError]
Type error: Argument 1 passed to App\Models\Task::setTracker() must be an instance of Carbon\Carbon, integer given, called in /var/www/app/Services/ShareLogic.php on line 60
and will not be catched
Thanks
Catching Throwable did the trick.
Have no idea why?
Anyone does?
It does not catch the exception because you are trying to catch \Exception which Symfony\Component\Debug\Exception\FatalThrowableError does not extend.
Instead try to catch the actual exception by importing it..
use Symfony\Component\Debug\Exception\FatalThrowableError;
And then you can do..
try {
//
} catch(FatalThrowableError e) {
//
}
Edit
Ok, so in addition to the above solution it seems PHP 7+ handles error a bit differently than PHP 5. So try this..
try {
//
} catch(Error $e) {
// This should work
} catch(Throwable $e) {
// This should work as well
}
Symfony's Debug component is much more sophisticated in order to log and report all kinds of errors but take look at this simple example (php 7.1.x):
<?php
class MyUncatchableError extends Exception {}
function myExceptionHandler($e) {
throw new MyUncatchableError('BANG: '.$e->getMessage());
}
set_exception_handler('myExceptionHandler');
$foo = true;
try {
$foo->modify();
} catch (Exception $e) {
echo 'nope';
} catch (MyUncatchableError $e) {
echo 'nope2';
}
What will be the outcome? Well:
Fatal error: Uncaught MyUncatchableError: BANG: Call to a member function modify() on boolean in /in/WJErU:6
Stack trace:
0 [internal function]: myExceptionHandler(Object(Error))
1 {main}
thrown in /in/WJErU on line 6
and you can't catch that exception because you should catch the original.. throwable here, which is Error for this kind of "error". You can catch it by catching "Error" class. And with PHP7 hierarchy it implements Throwable interface, that's why you can't catch it using Exception (because while Exception implements Throwable, Error is no an Exception - see: http://php.net/manual/en/language.errors.php7.php).
And this is true for PHP7+ because with 5.* there was no Throwable nor Error, and doing $foo->modify(); would just stop the script and return a Fatal Error. You can make your own error handler (set_error_handler) and throw an exception there (and Debug component does that for php 5.*) but this method does not work for Fatal Errors. Instead Debug component hooks into script shutdown and reads last error and throws FatalErrorException.
This description may not be completely accurate as I have't dug deeply into Symfony but you can get the idea here.

Php selective exception handling

I have a problem where I want to catch all exception except descendants of my custom exception.
Maybe bad design, but here it is (Simplified and names changed, but the code is quite accurate):
function doStuff()
{
try {
// code
if (something) {
// manually throw an exception
throw StuffError("Something is bad.");
}
// a third-party code, can throw exceptions
LibraryClass::arcaneMagic();
} catch (Exception $e) {
throw new StuffError("Error occured while doing stuff: "
. $e->getMessage());
}
}
/** My custom exception */
class StuffError extends Exception
{
function __construct($msg) {
parent::__construct('StuffError: ' . $msg);
}
}
However, the issue here is that I don't want the try-catch to intercept the manually throws StuffError. Or, seamlessly rethrow it or something.
As it is now, I'd get:
StuffError: Error occured while doing stuff: StuffError: Something is bad.
I want just:
StuffError: Something is bad.
How would I do it?
You can have multiple catch clauses, and the first one that matches will be the one that runs. So you could have something like this:
try {
do_some_stuff();
}
catch (StuffError $e) {
throw $e;
}
catch (Exception $e) {
throw new StuffError(Error occurred while doing stuff: " . $e->getMessage());
}
But you might want to rethink wrapping stuff like this. It obscures the real cause of the error. For one thing, you lose the stack trace. But it also complicates error handling, since now someone can't differentiate exception types the way you're trying to do, short of trying to parse the exception message (which is rather an anti-pattern in itself).
I might be misinterpreting you, but I think this is what you're looking for:
...
} catch (Exception $e) {
if (get_class($e) == 'StuffError' || is_subclass_of($e, 'StuffError')) {
throw $e;
} else {
throw new StuffError("Error occured while doing stuff: "
. $e->getMessage());
}
}
...
Replace your catch statement with the code above. It checks to see if the exception is a StuffError or a child class of StuffError. I'm still very confused at why you would need to throw a StuffError exception after you catch, but maybe that's just some weirdness coming from translating/cleaning your code.

How to Try Catch in symfony

Situation:
//trollCommand.php
[...]
foreach ($trolltypes as $type) { //$type=={"Frost","RandomBroken","Forest"}
try {
$output->writeln($type);
$troll={"get".$type."TrollType"}();
$output->writeln("TEST 1");
$troll->__load();
$output->writeln("TEST 2");
} catch (EntityNotFoundException $e) {
$output->writeln("WARNING: TROLL ENTITY DOES NOT EXIST.");
continue;
}
$output->writeln("TROLLING");
do_something_with_troll($troll);
}
getFrostTrollType loads ok, getForestTrollType should be loaded ok too, but before that, it is a problem, getRandomBrokenTrollType() deliberately does not exist, and then I see message in console:
Frost
Test 1
Test 2
TROLLING
RandomBroken
Test 1
[Doctrine\ORM\EntityNotFoundException]
Entity was not found.
//[EXIT FROM SCRIPT]
troll#troll-machine ~/trollSandbox/ $ _
it should be: WARNING: TROLL ENTITY DOES NOT EXIST. and then continue; but it does not happen
How to check existing of a object's method?
if you're trying to catch any exception, you should use a backslash before "Exception".
E.g.:
try{
//do stuff here
}
catch(\Exception $e){
error_log($e->getMessage());
}
If you don't use a backslash, the exception won't be caught. This is due to how namespaces are used in PHP / Symfony.
the Exception thrown by Doctrine is called Doctrine\ORM\EntityNotFoundException and you are catching EntityNotFoundException.
Thats a difference, the namespace matters.
to debug this, catch Exception instead and observe the type of the actual exception. then replace it.
Exception Type is - \Doctrine\ORM\EntityNotFoundException
Don`t forget starting "\"
Example -
try {
$entityManager = $this->getEntityManager();
$entityManager->remove($entity);
$entityManager->flush(); // save to the database
} catch (\Doctrine\ORM\EntityNotFoundException $ex) {
echo "Exception Found - " . $ex->getMessage() . "<br/>";
}

What's the `finally` keyword for in PHP?

Consider these two examples
<?php
function throw_exception() {
// Arbitrary code here
throw new Exception('Hello, Joe!');
}
function some_code() {
// Arbitrary code here
}
try {
throw_exception();
} catch (Exception $e) {
echo $e->getMessage();
}
some_code();
// More arbitrary code
?>
and
<?php
function throw_exception() {
// Arbitrary code here
throw new Exception('Hello, Joe!');
}
function some_code() {
// Arbitrary code here
}
try {
throw_exception();
} catch (Exception $e) {
echo $e->getMessage();
} finally {
some_code();
}
// More arbitrary code
?>
What's the difference? Is there a situation where the first example wouldn't execute some_code(), but the second would? Am I missing the point entirely?
If you catch Exception (any exception) the two code samples are equivalent. But if you only handle some specific exception type in your class block and another kind of exception occurs, then some_code(); will only be executed if you have a finally block.
try {
throw_exception();
} catch (ExceptionTypeA $e) {
echo $e->getMessage();
}
some_code(); // Will not execute if throw_exception throws an ExceptionTypeB
but:
try {
throw_exception();
} catch (ExceptionTypeA $e) {
echo $e->getMessage();
} finally {
some_code(); // Will be execute even if throw_exception throws an ExceptionTypeB
}
fianlly block is used when you want a piece of code to execute regardless of whether an exception occurred or not...
Check out Example 2 on this page :
PHP manual
Finally will trigger even if no exception were caught.
Try this code to see why:
<?php
class Exep1 extends Exception {}
class Exep2 extends Exception {}
try {
echo 'try ';
throw new Exep1();
} catch ( Exep2 $e)
{
echo ' catch ';
} finally {
echo ' finally ';
}
echo 'aftermath';
?>
the output will be
try finally
Fatal error: Uncaught exception 'Exep1' in /tmp/execpad-70360fffa35e/source-70360fffa35e:7
Stack trace:
#0 {main}
thrown in /tmp/execpad-70360fffa35e/source-70360fffa35e on line 7
here is fiddle for you. https://eval.in/933947
From the PHP manual:
In PHP 5.5 and later, a finally block may also be specified after or instead of catch blocks. Code within the finally block will always be executed after the try and catch blocks, regardless of whether an exception has been thrown, and before normal execution resumes.
See this example in the manual, to see how it works.
http://www.youtube.com/watch?v=EWj60p8esD0
Watch from: 12:30 onwards
Watch this video.
The language is JAVA though.
But i think it illustrates Exceptions and the use of finally keyword very well.

What is the PHP equivalent to Python's Try: ... Except:

I am a strong Python programmer, but not quite there when it comes to PHP. I need to try something, and if that doesn't work out, do something else.
This is what it would look like in Python:
try:
print "stuf"
except:
print "something else"
What would this be in PHP?
http://php.net/manual/en/language.exceptions.php
try {
print 'stuff';
} catch (Exception $e) {
var_dump($e);
}
Note: this only works for exceptions, not errors.
See http://www.php.net/manual/en/function.set-error-handler.php for that.
try {
// do stuff ...
} catch (Exception $e) {
print($e->getMessage());
}
See http://php.net/manual/en/language.exceptions.php
PHP does not natively support error catching like Python does, unless you override the default behavior and set your own error handler. PHP's try - catch was only recently added to the language in version 5, and it can only catch exceptions you explicitly throw.
So basically, PHP distinguishes between errors and exceptions. Errors haven't been modularized and made available to the user like they have been in Python. I believe that's related to the fact that PHP began as a collection of dynamic web scripts, grew and gained more features over time, and only more recently offered improved OOP support (i.e., version 5); whereas Python fundamentally supports OOP and other meta-functionality. And exception handling from the beginning.
Here's an example usage (again, a throw is necessary, or else nothing will be caught):
function oops($a)
{
if (!$a) {
throw new Exception('empty variable');
}
return "oops, $a";
}
try {
print oops($b);
} catch (Exception $e) {
print "Error occurred: " . $e->getMessage();
}
You can handle PHP errors like they were exceptions by using set_error_handler
In this error handler function you can throw various exception, according to error level for instance.
By doing this you can treat any error (including programming errors) in a common way.
PHP 5 has the exception model:
try {
print 'stuff';
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
}
Assuming you're trying to catch exceptions, take a look at http://php.net/manual/en/language.exceptions.php
You could try something like
try {
echo "Stuff";
} catch (Exception $e) {
echo "Something Else";
}

Categories