I'm trying to catch a Laravel exception inside my library.
namespace Marsvin\Output\JoomlaZoo;
class Compiler
{
protected function compileItem($itemId, $item)
{
$boom = explode('_', $itemId);
$boom[0][0] = strtoupper($boom[0][0]);
$className = __NAMESPACE__."\\Compiler\\".$boom[0];
try {
$class = new $className(); // <-- This is line 38
} catch(\Symfony\Component\Debug\Exception\FatalErrorException $e) {
throw new \Exception('I\'m not being thrown!');
}
}
}
This it the exception I'm getting:
file: "C:\MAMP\htdocs\name\app\libraries\WebName\Output\JoomlaZoo\Compiler.php"
line: 38
message: "Class 'Marsvin\Output\JoomlaZoo\Compiler\Deas' not found"
type: "Symfony\Component\Debug\Exception\FatalErrorException"
The name of the class is voluntarily wrong.
Edit 1:
I noticed that if I throw an exception inside the try statement I can catch the exception:
try {
throw new \Exception('I\'d like to be thrown!');
} catch(\Exception $e) {
throw new \Exception('I\'m overriding the previous exception!'); // This is being thrown
}
The problem is that you're trying to catch a FatalErrorException in your class, but Laravel won't let a fatal error get back there; it terminates immediately. If your were trying to catch a different kind of exception, your code would work just fine.
You can catch and handle fatal errors with an App::fatal method in app/start/global.php, but that won't help you deal with the exception from within your library, or to handle it with any specificity. A better option would be to trigger a "catchable" exception (something from Illuminate, for instance), or to throw a custom one based on the condition that you are trying to check.
In your case, if your goal is to deal with undefined classes, here's what I would suggest:
try {
$className = 'BadClass';
if (!class_exists($className)) {
throw new \Exception('The class '.$className.' does not exist.');
}
// everything was A-OK...
$class = new $className();
} catch( Exception $e) {
// handle the error, and/or throw different exception
throw new \Exception($e->getMessage());
}
Related
I'm trying to do a very basic exception try catch, but it doesn't catch.
$id =0;
try {
$question = $this->model->find($id); // will not find anything since $id = 0
$question->delete(); // throw an exception
return true;
} catch (\Exception $e) {
dd ('hello'); // should end up here, but no?!?!?
} catch (FatalThrowableError $f) {
echo ("fatal"); // or here... but no.
}
but the catch doesn't "catch". I get an Fatal error in the browser saying that delete was called on a null object. But that's exactly what I was trying to do: do a delete on a null object (id = 0 is not in the DB), to test the exception.
I have tried
use Symfony\Component\Debug\Exception;
use Symfony\Component\Debug\Exception\FatalThrowableError;
or simply
Exception;
FatalThrowableError;
Also, having the \Exception $e or Exception $e (with or without ) doesn't change anything.
Note that if I add a line like $foo = 4/0 I get into the Exception section (dd (hello)).
in .env APP_DEBUG=true, APP_LOG_LEVEL=debug
I'm on Laravel 5.5 using PHP 7.0.10 on windows 7.
http://php.net/manual/en/language.errors.php7.php
As the Error hierarchy does not inherit from Exception, code that uses
catch (Exception $e) { ... } blocks to handle uncaught exceptions in
PHP 5 will find that these Errors are not caught by these blocks.
Either a catch (Error $e) { ... } block or a set_exception_handler()
handler is required.
You can, additionally, catch (\Throwable $e) {} to account for both Error and Exception types.
When i initiate a class which does not exist , It throws the error, I Don't want to halted by that error . So i try trycatch method , But it still giving me same error, Can someone explain why this error is not been catched
I tried
try{$obj = new classname();}
catch(Exception $e){ echo 'class does not exist, move on' ;}
Fatal error: Class 'classname' not found in C:\WampDeveloper\Websites\localhost\webroot\index.php on line 4
Can someone explain why this error can not be catched ?
Is their is another way to catch and handle this kind of errors ?
UPDATE
We can catch mysql fatal errors by try catch method , So don't say fatal errors can not be handeled by try catch method
Two ways to solve this, use a autoloader that runs a custom written function for each object that does not exist so you can try to "include" a file on demand.
function autoload($objname){
if(is_readable(($f = '/path/to/class/'.$objname.'.php'))){
include $f;
} else {
throw Exception("$f does not exist");
}
}
spl_autoload_register('autoload');
new classname(); // try to load /path/to/class/classname.php
Or you can upgrade to PHP 7 where the error logic has had little overhaul:
Hierarchy
Throwable
Error
ArithmeticError
DivisionByZeroError
AssertionError
ParseError
TypeError
Exception
So a code like this would work:
try{
$obj = new classname();
} catch(Error $er){
echo 'class does not exist, move on';
} catch(Exception $ex){
echo 'a custom exception has been thrown:' . $ex->getMessage();
} catch(Throwable $t){
// Obsolete code, as Throwables are either Error or Exception, that were caught above.
}
Here is my code:
try {
if ( condition 1 ) {
throw;
} else {
// do something
}
// some code here
if ( condition 2 ){
throw;
}
} catch (Exception $e) {
echo "something is wrong";
}
As you see, my catch block has its own error message, And that message is a constant. So really I don't need to pass a message when I use throw like this:
throw new Exception('error message');
Well can I use throw without anything? I just need to jump into catch block.
Honestly writing an useless error message is annoying for me.
As you know my current code has a syntax error: (it referring to throw;)
Parse error: syntax error, unexpected ';' in {path}
message parameter is optional in the Exception constructor. So if you don't have/want to put - just don't:
throw new Exception;
But you still must throw an instance of the Exception class (or a class that extends it), since it is a part of the php language syntax.
If you want all your exceptions to have the same message, you can extend it and define the message in your class:
class AmbiguousException extends Exception {
public function __construct($message = 'Something is wrong.', $code = 0, Exception $previous = null) {
parent::__construct($message, $code, $previous);
}
}
Then:
throw new AmbiguousException();
You can use the below throw everytime you need.
throw new Exception();
and catch will remain same as your code.
As stated in the PHP manual:
The thrown object must be an instance of the Exception class or a subclass of Exception. Trying to throw an object that is not will result in a PHP Fatal Error.
You can throw an exception without any message:
throw new Exception();
Perhaps something to help you from duplicating the same exception is as follows:
$e = new Exception('something is wrong');
try {
throw $e;
} catch (Exception $ex) {
echo $ex->getMessage();
}
You can create an instance with default message and then throw that instance.
$Exception = new Exception("some error message!");
try {
throw $Exception;
} catch (Exception $ex) {
var_dump($ex);
}
You cannot use the throw keyword on its own. However, you can use throw new Exception(); without specify the $message parameter, because it'll just fallback to the default message. Check out the Exceptions section in the PHP manual: http://php.net/manual/en/language.exceptions.extending.php
I'm having trouble catching an exception in PHP
Here's my code.
try {
require $this->get_file_name($action);
}
catch (Exception $e) {
//do something//
}
and the method being called
private function get_file_name($action) {
$file = '../private/actions/actions_'.$this->group.'.php';
if (file_exists($file) === false) {
throw new Exception('The file for this '.$action.' was not found.');
}
else {
return $file;
}
}
Resulting in:
Fatal error: Uncaught exception 'Exception' with message $action was not found.'
Exception: The file for this $action was not found.
However If I put a try-catch block inside of the function and call the function, I'm able to catch the exception no problem.
What am I doing wrong?
If you are catching the Exception inside a namespace, make sure that you fall back to the global namespace:
...
}(catch \Exception $e) {
...
}...
You can also have a look at the following resources:
Why isn't my Exception being caught by catch?
http://php.net/manual/en/language.exceptions.php, top note by user zmunoz
I can't see all of the class body but If You want to use method out of the class it should be Public not Private.
Try to check if file You trying to get exists:
var_dump($file = '../private/actions/actions_'.$this->group.'.php');
IMO there is no file in this path
I am trying to understand what the best approach would be to handle Exceptions in the following scenario:
I have a class employee:
class employee extends person {
private $salary;
private $baseSalary = 6.5;
function __construct($f, $m, $l, $a,$fsalary=0){
if(!is_numeric($fsalary)){
throw new Exception("Age supplied is not a number", 114);
}
parent::__construct($f, $m, $l, $a);
$this->salary=$fsalary;
}
function GetDetails(){
return parent::GetName().
"<br/>".
$this->salary;
}
function __toString(){
return $this->GetDetails();
}
}
And using this:
try{
if(!$f = new employee("Sarah", "Sebastian", "Pira", "abc")){
throw new Exception();
}
else {
echo $f;
}
}
catch (Exception $e){
echo "<br/>";
echo var_dump($e);
}
Now I would think it would be a good idea to throw an exception in the class and then use just one catch block in all the scripts that would be using an employee object - But this doesn't seem to work - I need to have a try catch block within the class - Is this the correct way of looking at this?
Thanks
I think what you're saying is that you want to do something like this:
try {
class Employee extends Person {
// ...blah blah...
}
}
catch(Exception $e) {
// handle exception
}
...and then be able to insantiate it in other classes, without explicitly catching any exceptions:
// try { << this would be removed
$employee = new Employee();
// }
// catch(Exception $e) {
// (a whole bunch of code to handle the exception here)
// }
You can't do that, because then the try/catch block in the class will only catch any exceptions that occur when defining the class. They won't be caught when you try to instantiate it because your new Employee line is outside the try/catch block.
So really, your problem is that you want to be able to re-use a try/catch block in multiple places without re-writing the code. In that case, your best solution is to move the contents of the catch block out to a separate function that you can call as necessary. Define the function in the Employee class file and call it like this:
try {
$employee = new Employee();
$employee->doSomeStuff();
$employee->doMoreStuffThatCouldThrowExceptions();
}
catch(Exception $e) {
handle_employee_exception($e);
}
It doesn't get rid of the try/catch block in every file, but it does mean that you don't have to duplicate the implementation of the exception-handling all the time. And don't define handle_employee_exception as an instance method of the class, do it as a separate function, otherwise it will cause a fatal error if the exception is thrown in the constructor because the variable won't exist.
You should read more about Exceptions in PHP.
You can handle exceptions within the methods of the class, sure. But you should rethink how you want to do this and... why.
Good practice is also creating own exception class, so you are able to distinguish exceptions thrown by your module / class from the exceptions thrown by something else. It looks like that (see more):
class EmployeeModule_Exception extends Exception {}
and when it comes to throwing exception:
// the second parameter below is error code
throw new EmployeeModule_Exception('some message', 123);
Catching is similar, only the below example will catch only your module's exceptions:
try {
// some code here
} catch (EmployeeModule_Exception $e) {
// display information about exception caught
echo 'Error message: ' . $e->getMessage() . '<br />';
echo 'Error code: ' . $e->getCode();
}