So i'm trying to learn about exceptions. And i've come accross something people often do , but dont really explain why they do it and how it works. Maybe this is something that speaks for itself but I still dont get it, I apologize if this question might come over as a bad question.
Basically this is the code I'm working with:
catch(Exception $e) {
echo 'Message: ' .$e->getMessage();
}
What is $e where is this variable defined. I have an idea.
What i'm thinking is that you're assigning the exception object to the variable $e but i'm not sure. Shouldnt it be catch (Exception = $e) ?
It works pretty much the same as function parameters:
function foo(Bar $bar) { ... }
You use a type hint Bar followed by the parameter name $bar, and that declares the variable.
In the case of try..catch, that declaration happens in catch:
catch (Exception $e) { ... }
This uses the type hint Exception, which here is used to specify which kinds of exceptions the catch is supposed to catch. You can limit the catch to specific kinds of exceptions and/or define multiple different catch blocks for different kinds of exceptions. The exception itself is then available in the variable $e. You can use any arbitrary variable name here, just as for function parameters.
Uhm, now that i think about it, i have always considered the Exception $e to be the input for the catch() call.
As far as i know, you are not defining $e, as it is already thrown, you are just passing it to the catch() block, as you would do with a function name($input){}
In this code
catch(Exception $e) {
echo 'Message: ' .$e->getMessage();
}
The keyword Exception is the type for the parameter $e.
In PHP Exception is the base exception class that all exceptions derive from so that catch block is a catch-all for all exceptions.
i.e. You might want multiple handlers for different exception types before the catch-all:
try {
someOperation($parameter);
} catch(DatabaseException $e) {
echo 'Database Exception: ' .$e->getMessage();
} catch(Exception $e) {
echo 'General Exception: ' .$e->getMessage();
}
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.
A very simple question from someone without much experience. The following try catch block has the section, "(Exception $e)" : is this like sql, where $e becomes an alias of Exception? If so, is this type of alias assignment used elsewhere in php, because I haven't come across it? I have searched for hours without being able to find an explanation on the web.
function inverse($x) {
if (!$x) {
throw new Exception('Division by zero.');
}
else return 1/$x;
}
try {
echo inverse(5) . "<br/>";
echo inverse(0) . "<br/>";
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "<br/>";
}
echo 'Hello World';
What you mention is a filter construction. It resembles a declaration as known from other, declarative languages. However it has a different meaning in fact. Actually php does not have the concept of an explicit declaration (which is a shame...).
Take a look at this example:
function my_func($x) {
try {
/* do something */
if (1===$x)
throw new SpecialException('x is 1.');
else if (is_numeric($x)) }
throw new SpecialException('x is numeric.');
else return $x;
}
catch (SpecialException $e) {
echo "This is a special exception!";
/* do something with object $e of type SpecialException */
}
catch (Exception $e) {
echo "This is a normal exception!";
/* do something with object $e of type SpecialException */
}
}
Here it becomes clear what the construction is for: it filters out by type of exception. So the question which of several catch blocks is executed can be deligated to the type of exception having been thrown. This allows a very fine granulated exception handling, where required. Without such feature only one catch block would be legal and you'd have to implement conditional tests for potential exception types in each catch block. This feature makes the code much more readable, although it is some kind of break in the php syntax.
You don't have to, but you can create own exception classes with special behavior and, more important, accepting and carrying more information about what actually happened.
It's OO PHP. The $e is an instance of the exception object.
$e could easily be labelled anything else, so long as it's referred to thereon when you want to getmessages, etc.
For instance;
try {
echo inverse(5) . "<br/>";
echo inverse(0) . "<br/>";
} catch (Exception $oops) {
echo 'Caught exception: ', $oops->getMessage(), "<br/>";
}
How can I know during runtime that my code threw a Warning?
example
try {
echo (25/0);
} catch (exception $exc) {
echo "exception catched";
}
throws a "Warning: Division by zero" error that i can not handle on my code.
You're looking for the function set_error_handler(). Check out the sample code in the manual.
Make sure that you don't only suppress the error warnings, but instead silently redirect them to a log file or something similar. (This helps you track down bugs)
You need to handle the exception yourself as follows.e.g
function inverse($x)
{
if(!$x)
{
throw new Exception('Division by zero.');
}
else
{
return 1/$x;
}
}
try
{
echo inverse(5);
echo inverse(0);
}
catch (Exception $e)
{
echo $e->getMessage();
}
You need to install an error handler that converts old style php "errors" into exceptions. See an example here
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);
}