Try/Catch block in PHP not catching Exception

Php

Php Problem Overview


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

Php Solutions


Solution 1 - Php

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

Solution 2 - Php

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.

Solution 3 - Php

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.

Solution 4 - Php

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

Solution 5 - Php

\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/

Solution 6 - Php

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

Solution 7 - Php

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';
?>

Solution 8 - Php

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

Solution 9 - Php

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

Solution 10 - Php

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

Solution 11 - 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

Solution 12 - Php

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

Solution 13 - Php

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

Solution 14 - Php

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.

Solution 15 - Php

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);
}

Solution 16 - Php

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionKrassiView Question on Stackoverflow
Solution 1 - PhpPijusnView Answer on Stackoverflow
Solution 2 - PhpEnethionView Answer on Stackoverflow
Solution 3 - PhpVladimir DespotovicView Answer on Stackoverflow
Solution 4 - PhpRowinson GallegoView Answer on Stackoverflow
Solution 5 - PhpGnast973View Answer on Stackoverflow
Solution 6 - Phpuser5528384View Answer on Stackoverflow
Solution 7 - PhpsfrenchView Answer on Stackoverflow
Solution 8 - PhpYawarView Answer on Stackoverflow
Solution 9 - PhpßãlãjîView Answer on Stackoverflow
Solution 10 - PhpKoushik DasView Answer on Stackoverflow
Solution 11 - Phpuser2950254View Answer on Stackoverflow
Solution 12 - PhpMr HeelisView Answer on Stackoverflow
Solution 13 - PhpgoatView Answer on Stackoverflow
Solution 14 - PhpFauzie AdriansyahView Answer on Stackoverflow
Solution 15 - PhpBlackView Answer on Stackoverflow
Solution 16 - PhpgladdView Answer on Stackoverflow