I'm trying to catch a PDOException in laravel 3 but it seems as if I cannot do this. My code is as follows:
try{
DB::connection()->pdo->beginTransaction();
Myobject::create($cleaned_input_array);
// do other stuff that could possibly throw a custom exception
DB::connection()->pdo->commit();
}
catch(\PDOException $e)
{
DB::connection()->pdo->rollBack();
return HTTP_STATUS::response(BAD_REQUEST, array("error creating");
}
catch(Exception $e)
{
DB::connection()->pdo->rollBack();
return HTTP_STATUS::response(BAD_REQUEST, array($e->getMessage()));
}
The general exception is caught if the other parts in the 'try' throw an exception. If they do not, everything runs clean. If the create has an issue executing the MYSQL statement it does not throw a PDOException, it is only throwing a general Exception.
A model wouldn't actually throw PDOException, that would be caught internally and a \Illuminate\Database\QueryException would be thrown instead, try catching that.
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.
I have the following situation:
try {
DB::beginTransaction();
$task = new Task();
$task->setTracker("");
//thrown \Symfony\Component\Debug\Exception\FatalThrowableError
DB::commit();
}catch (\Exception $e){
DB::rollBack();
Log::error($e);
//throw $e;
}
I am not entering to the catch area.
Any idea why?
update
This is the error thrown:
[Symfony\Component\Debug\Exception\FatalThrowableError]
Type error: Argument 1 passed to App\Models\Task::setTracker() must be an instance of Carbon\Carbon, integer given, called in /var/www/app/Services/ShareLogic.php on line 60
and will not be catched
Thanks
Catching Throwable did the trick.
Have no idea why?
Anyone does?
It does not catch the exception because you are trying to catch \Exception which Symfony\Component\Debug\Exception\FatalThrowableError does not extend.
Instead try to catch the actual exception by importing it..
use Symfony\Component\Debug\Exception\FatalThrowableError;
And then you can do..
try {
//
} catch(FatalThrowableError e) {
//
}
Edit
Ok, so in addition to the above solution it seems PHP 7+ handles error a bit differently than PHP 5. So try this..
try {
//
} catch(Error $e) {
// This should work
} catch(Throwable $e) {
// This should work as well
}
Symfony's Debug component is much more sophisticated in order to log and report all kinds of errors but take look at this simple example (php 7.1.x):
<?php
class MyUncatchableError extends Exception {}
function myExceptionHandler($e) {
throw new MyUncatchableError('BANG: '.$e->getMessage());
}
set_exception_handler('myExceptionHandler');
$foo = true;
try {
$foo->modify();
} catch (Exception $e) {
echo 'nope';
} catch (MyUncatchableError $e) {
echo 'nope2';
}
What will be the outcome? Well:
Fatal error: Uncaught MyUncatchableError: BANG: Call to a member function modify() on boolean in /in/WJErU:6
Stack trace:
0 [internal function]: myExceptionHandler(Object(Error))
1 {main}
thrown in /in/WJErU on line 6
and you can't catch that exception because you should catch the original.. throwable here, which is Error for this kind of "error". You can catch it by catching "Error" class. And with PHP7 hierarchy it implements Throwable interface, that's why you can't catch it using Exception (because while Exception implements Throwable, Error is no an Exception - see: http://php.net/manual/en/language.errors.php7.php).
And this is true for PHP7+ because with 5.* there was no Throwable nor Error, and doing $foo->modify(); would just stop the script and return a Fatal Error. You can make your own error handler (set_error_handler) and throw an exception there (and Debug component does that for php 5.*) but this method does not work for Fatal Errors. Instead Debug component hooks into script shutdown and reads last error and throws FatalErrorException.
This description may not be completely accurate as I have't dug deeply into Symfony but you can get the idea here.
I have the following script.
According to http://php.net/manual/en/class.pdoexception.php, You should not throw a PDOException from your own code.
But I want the same catch to be performed whether a PDOException or the exception that I threw for an invalid foo.
I've also been told that I should never catch the generic Exception, but only catch specific Exceptions.
How should this be implemented?
try {
db::db()->beginTransaction();
//Do a bunch of queries, and a PDO exception will be thrown upon error
if($foo($bar)) {throw new Exception('Invalid foo.');}
db::db()->commit();
} catch (PDOException $e) {
db::db()->rollBack();
//Maybe do some other stuff
}
Something like
try {
db::db()->beginTransaction();
//Do a bunch of queries, and a PDO exception will be thrown upon error
if($foo($bar)) {throw new RuntimeException('Invalid foo.');}
db::db()->commit();
} catch (PDOException $e) {
db::db()->rollBack();
//Maybe do some other stuff
} catch (RuntimeException $e) {
//foo invalid
}
for the first time i came across try, throw catch statement in PHP, and i felt this could be the better way for handling errors as i was quite messing my error handlers with lots of if else statements, however as i am performing CRUD operations on my script i wanted my error handlers to perform two task.
display the user readable or
custom error message back to the
user.
catch all the error in a file for
me to read.
i am using the following code..
try
{
$name = filter_var($_POST['name'], FILTER_SANITIZE_STRING);
if($cname == $name)
{
throw new Exception('Sorry, Please Change the value to update ');
}
$sth = $dbh->prepare("UPDATE countries SET name = :name WHERE id = :cid");
$sth->bindParam(':name', $name);
$sth->bindParam(':cid', $cid);
$sth->execute();
}
catch(PDOException $e)
{
echo $e->getMessage();
file_put_contents("resources/logs/Connection-log.txt", DATE.PHP_EOL.$e->getMessage().PHP_EOL.PHP_EOL, FILE_APPEND);
}
if the condition $cname == $name is true i just want to display the error 'Sorry, Please Change the value to update, however this is not happening here, instead it throws the Fatal Error with this message.
Fatal error: Uncaught exception 'Exception' with message 'Sorry, Please Change the value to update ' in /Applications/MAMP/htdocs/kokaris/administrator/resources/library/models/countries.php:24 Stack trace: #0 /Applications/MAMP/htdocs/kokaris/administrator/location-manager.php(43): include() #1 {main} thrown in /Applications/MAMP/htdocs/kokaris/administrator/resources/library/models/countries.php on line 24
how do i achieve this?
thank you..
Your catch is catching a PDOException :
catch(PDOException $e)
While you are throwing a Exception :
throw new Exception('Sorry, P...
PDOException is a sub-class of Exception, which means that :
A PDOException is an Exception
But an Exception is not a PDOException.
So, when you are trying to catch a PDOException, your catch will not also catch Exception.
If you want your Exception to be catched, you must use something like this :
try {
}
catch (PDOException $e) {
// deal with PDOException
}
catch (Exception $e) {
// deal with all other kinds of exceptions
}
In this case, the catch PDOException can be avoided, if you do not want to do some special treatment for PDOExceptions, and just want all exceptions to be dealt with the same way :
try {
}
catch (Exception $e) {
// deal with all kinds of exceptions
}
You are throwing an Exception but catching a PDOException.
You should catch the same as you throw, so you might want to change your catch to:
catch(Exception $e)
Or if you also want to catch that PDOException and not do the file_put_contents for your own excpetion, add a catch for your specific Exception.
YOu could ofcourse also change your throw to PDOException, same thing basically.
I been searching for this and I just seem to run into the same articles, in this code:
try
{
//some code
}
catch(Exception $e){
throw $e;
}
Where does $e gets stored or how the webmaster see it? Should I look for a special function?
An Exception object (in this case, $e) thrown from inside a catch{} block will be caught by the next highest try{} catch{} block.
Here's a silly example:
try {
try {
throw new Exception("This is thrown from the inner exception handler.");
}catch(Exception $e) {
throw $e;
}
}catch(Exception $e) {
die("I'm the outer exception handler (" . $e->getMessage() . ")<br />");
}
The output of the above is
I'm the outer exception handler (This is thrown from the inner exception handler.)
One nice thing is that Exception implements __toString() and outputs a call stack trace.
So sometimes in low-level Exceptions that I know I'm gonna want to see how I got to, in the catch() I simply do
error_log($e);
$e is an instance of Exception or any other class that extended from Exception. Those objects have some specific attributes and methods in common (inherited from the Exception class) you can use. See the chapter about exceptions and the Exception member list for more details.
I'm assuming your using some sort of third party code/library with this code in it that is throwing the exception into your code. You simply have to be ready for an exception to be thrown to catch it, then you can log it/display it however you want.
try {
$Library->procedure();
catch(Exception $e) {
echo $e->getMessage(); //would echo the exception message.
}
For more information read the PHP manual's entry on Exceptions.
The lines:
catch(Exception $e){
throw $e;
}
Don\t make sense. When you catch an Exception you're suppose to do something with the exception like:
catch(Exception $e){
error_log($e->getMessage());
die('An error has occurred');
}
But in your case the Exception is thrown directly to an outer try-block which would already happen.
If you change your code to:
//some code
Would create the exact same behaviour.