I have some code that looks like this
# Try to import file
try
{
DataManager::fileImport($_FILES['datafile']['tmp_name'],
$_POST['zones'], $_POST['statuses']);
}
catch(Exception $e)
{
print 'Herp.';
$response->body = Helpers::getVarDump($e);
}
DataManager::fileImport is literally a one-line function that throws a normal Exception:
static function fileImport($filepath, $zones, $statuses)
{
throw new Exception('SOME EXCEPTION');
}
And yet I get
Fatal error: Uncaught exception 'Exception' with message 'SOME EXCEPTION'...
From the try block. Also 'Herp.' is never printed. Why doesn't the Exception trigger the catch block?
EDIT: I should mention I'm using Tonic and PHP 5.3.9
EDIT AGAIN: Here's DataManager (with names replaced with ... for anonymity) http://pastebin.com/daHWBJDC
Solution
I neglected to specify use \Exception; in the file containing the try/catch.
Pondering
I know it's intentional that each namespace in PHP should define its own Exception for many reasons, but I still find it odd that catch(Exception e) didn't cause any errors when Exception in that context wasn't defined. If I were to write new Exception() I would get an error.
Oh well, at least I learned something.
Strange. If i run this code i get the "Herp."
<?php
class DataManagerTest {
static function fileImport($filepath, $zones, $statuses)
{
throw new Exception('SOME EXCEPTION');
}
}
# Try to import file
try
{
DataManagerTest::fileImport("param1","param2","param3");
}
catch(Exception $e)
{
print 'Herp.';
}
?>
You might have an issue with your DataManager class because i copied your code, adapted it to run and i get the exception handled... You problem is elsewhere...
class DataManager {
static function fileImport($filepath, $zones, $statuses){
throw new Exception('SOME EXCEPTION');
}
}
try{
DataManager::fileImport('', '', '');
}catch(Exception $e){
print 'Herp.';
}
Results in
Herp.
4 years later...
#Hubro, thank you for saving me with that namespace fix!
It does seem counterintuitive at first that it's necessary when throwing a root-level Exception, even though it ultimately makes sense in the general context of namespaces.
For anyone who doesn't want to utilize #Hubro's file-level fix:
use \Exception;
You could instead add the backslash in front of Exception in the higher level catch block:
} catch (\Exception $e) {
We could all benefit from someone smarter than me providing suggestions on best practices around defining a custom Exception for each namespace. Any takers?
Related
I tried to catch an exception inside a PHPUnit test but it does not work as I expected. The exception seems to be caught in a higher level and I do not understand why.
public function testException()
{
echo 'Enter';
try {
throw new Exception('error.');
} catch (Exception $e) {
echo 'catch Exception';
}
echo 'End';
}
In the output only 'Enter' is visible. I do not reach the 'End'.
(I am using PHP7)
Thanks
Edit:
Replacing all Exception with \Exception solved my issue
Handling exceptions can be tricky, especially when they are called Exception :-)
Just look at all the feedback this (almost the same) question has generated.
Now, the exception is not caught only if does not match to the expected class. In this case it is definitely because of non-precise Exception class names specification, which will most certainly be fixed by specifying them as \Exception.
As smartly put by a commenter from the mentioned question thread:
Without the backslash Exception is specific to the namespace and won't be matched (or caught).
I want to catch a specific Exception and handle it properly. However, I have not done this before and I want to do it in the best way.
Will it be correct to create a separate class something like
class HandleException extends Exception
{
//my code to handle exceptions;
}
and in it have different methods handling the different exception cases? As far as I understand, the Exception class is like an "integrated" class in php so it can be extended and if an Exception is caught it is not obligatory to terminate the flow of the program?
And, an instance of this class will be created when an exception is caught? Sth. like
catch ( \Exception $e ) {
$error = new HandleException;
}
You CAN extend the basic Exception object with your own, to provide your own exception types, e.g.
class FooExcept extends Exception { .... }
class BarExcept extends Exception { .... }
try {
if ($something) {
throw new FooExcept('Foo happened');
} else if ($somethingelse) {
throw new BarExcept('Bar happened');
}
} catch (FooExcept $e) {
.. foo happened, fix it...
} catch (BarExcept $e) {
... bar happened, fix it ...
}
If an Exception is caught, then the program DOESN'T necessarily have to abort. That'd be up to the exception handler itself. But if an exception bubbles always back up to the top of the call stack and ISN'T caught, then the entire script will abort with an unhandled exception error.
From the manual
Multiple catch blocks can be used to catch different classes of
exceptions. Normal execution (when no exception is thrown within the
try block) will continue after that last catch block defined in
sequence. Exceptions can be thrown (or re-thrown) within a catch
block.
So you can do something like this:
try {
// some code
} catch ( HandleException $e ) {
// handle sthis error
} catch ( \Exception $e ) {
// handle that error
}
This will handle different exceptions. You can also use the finally keyword with newer versions of PHP.
I have a code like this one:
public function one()
{
try {
$this->two();
} catch (Exception $E) {
$this->three();
}
}
How can i test that $this->three() function is called?
I've tried to "mock by code" $this->two() and throw error instead of it's original code, but that ends up with error caught by phpunit itself.
Tried setExpectedException, but it also doesn't solve the problem - catch runs inside phpunit again and just ignored.
Function $this->three() never called in both cases.
Thanks!
The problem was that the described method were in a class which was placed in a namespace containing it's own Exception implementation. So I was catching an \Namespace\Exception while throwing an \Exception.
Throwing correct exception did the thing.
#sectus, thank you!
I'm using the Yii 2 framework and it uses a number of extended exceptions and I'm having an issue with them where I threw a UserException but it ended up being caught by the base Exception but I'm not sure why!?
The code:
try {
//........
if ($reader->count() > 0) {
if (!$already_active) {
//.....
} else {
throw new UserException('You have already activated your account; you may continue to login.');
}
}
} catch (\Exception $e) {
// User exception above is caught in here?
} catch (UserException $e) {
// Rethrow the exception
throw $e;
}
Shouldn't the User Exception be passed onto and caught by the second catch?
From http://php.net/manual/en/language.exceptions.php
When an exception is thrown, code following the statement will not be executed, and PHP will attempt to find the first matching catch block.
The catch block for Exception will be executed since Exception is a parent of UserException and therefore any object of type UserException is also of type Exception.
Therefore you should refactor your code to have the catch block for child classes first. In your case UserException should be first.
If you take a look at UserException class you can see:
class UserException extends Exception
Therefore, Exception has the higher priority.
However you can do just:
//if something's wrong
throw new \yii\base\UserException('You have already activated your account; you may continue to login.');
In some libraries it is common practice to make custom Exception classes for every error condition, like:
class FileNotFound_Exception extends Exception {}
You can handle certain type of Exception, however you cannot read all source code of all libraries to remember each Exception class, and cannot take full advantage of using custom Exceptions. Most of time I just catching them with base Exception class:
catch (Exception $e)
{
// log and display friendly error
}
Is there other ways to have benefit of custom Exception classes, without writing long list of catch blocks?
I like Exceptions, but don't know how to use them properly. Thank you.
The benefit of having your own Exception class is that you, as the author of the library, can catch it and handle it.
try {
if(somethingBadHappens) {
throw MyCustomException('msg',0)
}
} catch (MyCustomException $e) {
if(IcanHandleIt) {
handleMyCustomException($e);
} else {
//InvalidArgumentException is used here as an example of 'common' exception
throw new InvalidArgumentException('I couldnt handle this!',1,$e);
}
}
Well, custom exception classes lets you route your errors properly for better handling.
if you have a class
class Known_Exception extends Exception {}
and a try catch block like this:
try {
// something known to break
} catch (Known_Exception $e) {
// handle known exception
} catch (Exception $e) {
// Handle unknown exception
}
Then you know that Exception $e is an unknown error situation and can handle that accordingly, and that is pretty useful to me.