I am trying to catch a custom exception, but keep getting an Exception 'CustomException' is never thrown in the corresponding try block inspection error for the following scenario:
class CustomException extends Exception { }
class Test {
/**
* #throws CustomException
*/
public function willFail()
{
throw new CustomException('I failed');
}
}
$test = new Test;
try {
$test->willFail();
} catch (CustomException $e) {
echo $e->getMessage();
}
The above example works exactly as expected, aside from PhpStorm giving me the inspection error.
I've searched everywhere and can't find out how to fix this without disabling the inspection entirely. Any help would be greatly appreciated!
Just in case anyone else runs into this problem themselves in the future, I'm posting the solution to this problem.
This was fixed by updating "Call tree analysis depth" to "1" in Preferences > Languages & Frameworks > PHP. Click on the "Analysis" tab and update the setting there.
Related
As of PHP 7 it's possible to catch Fatal Errors by catching either Error class or Throwable interface, but for some reason I can't manage to do that when "Fatal Error: trait not found" is triggered.
try {
class Cars {
use Price;
}
} catch (Error $e) {
echo $e->getMessage(); // Output : Fatal error: Trait 'Price' not found in [..] on line [..]
}
The error not caught!! So I came up with a solution
try {
if (trait_exists('Price')) {
class Cars{
use Price;
}
} else {
throw new Error('Trait Price not found');
}
} catch (Error $e) {
echo $e->getMessage(); // Output : Trait Price not found
}
Why that Fatal Error in the first example wasn't caught?
Is my approach in the second example is the only way to do it?
Short answer: not all errors are catchable, some are still being upgraded to the new error/exception model.
PHP 7.0 let you catch creating a missing class:
$foo = new NotAClass;
PHP 7.3 will let you catch errors about parent classes not existing (see bug #75765):
class Foo extends NotAClass {}
However, you still can't catch a missing trait (there's a note on the Github issue for the above bug about this being harder to fix):
class Foo { use NotATrait; }
Note: HHVM is apparently fine catching any and all of these, since it doesn't care what you think about the rules (and partly because this sort of thing is much easier in a fully-compiled environment).
See https://3v4l.org/L0fPA for a demo.
And yes, as was mentioned in the comments, please try and not rely on catching missing classes / traits at run-time. You should know your class hierarchy way earlier that that.
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 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!
My exception does not seem to be bubbling up from the parent constructor.
Here's a simplified version:
class importer {
public function __construct()
{
$this->getFile(); // fills out $file with name or false on failure
if (!$this->file) {
throw new Exception("Sorry no file, so no can do!");
}
}
}
class childImporter extends importer {
pubclic function __construct()
{
parent::__construct();
}
}
try {
new childImporter();
nextFunction();
} catch (Exception $e) {
echo $e->getMessage();
}
nextFunction never gets called, and the catch block doesn't get run either, the whole thing throws an uncaught exception fault and stops.
I thought exceptions were supposed to bubble up?
Or is the code above supposed to work and something else is going wrong?
So for anyone else having a similar issue the problem was, as cbuckley pointed out, an issue with namespacing.
I changed both occurrences of Exception to \Exception which caught it nicely.
I wasn't getting any other namespace errors in my ide as PHPStorm had very nicely auto-imported an exception class of Symfony\Component\Config\Definition\Exception\Exception from who knows where (as I am not using any Symfony components anywhere else!).
Hope this helps someone who has also had a really long day!
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?