My code is
try{
$this->_db->beginTransaction();
$stmt = $this->_db->prepare("...");
$stmt->execute(array($var1, $var2));
...
} catch (Exception $e) {
$stmt->rollBack();
}
I want to log this action to my log file with a function
as you see this one meant to save errors in transaction. Another one should also save the succeeded attempts. BUT if I put them inside of try{} and catch{} they not working for some reason. outside it does work good but I'm not sure what exactly should I check here for true/false to see the result outside of try/catch.
Thanks for your answers. I'm just learning so my questions might be stupid. Sorry for this. =)
Update.
What I've tried to do is:
try{...
} catch (Exception $e) {
$stmt->rollBack();
file_put_contents(LOG_CONST, date("r")." UderID: ".$id." Error: ".$e->getMessage()."\n", FILE_APPEND);
}
And it didn't put anything.
Update 2
Not sure if I have to add a new details here or I should answer to myself... Anyway. Right now I'm trying this code
try{
$this->_db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->_db->beginTransaction();
$stmt = $this->_db->prepare
..................
$stmt->execute(array($var));
file_put_contents(DATACHANGE_LOG, date("r")." ".n307." UderID: ".$id."\n", FILE_APPEND);
$this->_db->commit();
} catch (Exception $e) {
file_put_contents(DATACHANGE_LOG, date("r")." Hello! \n", FILE_APPEND);
$stmt->rollBack();
}
I have a same result with valid and not valid data at my log file. It's the first row from try{} which means that rollback is not affective at file_put_contents. However if the data at queries not valid rollback working agains them and there is no changes at DB. But the row before rollback never works.
Errors are enabled but it doesn't show anything... I just can't give up I have to understand it...
Update 3
What is invalid data?
I've tried MySQL errors/table,row errors.
Why do I need this at all?
I'm learning and doing a lot of things that I don't need actually just to understand how it works. As I see now it throwing errors in MySQL itself so really not useful logger in this particular case. Anyway I've got my errors and here is it.
Working code:
try{
$this->_db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->_db->beginTransaction();
$stmt = $this->_db->prepare
QUERIES
$stmt->execute(array($var));
file_put_contents(DATACHANGE_LOG, date("r")." ".n307." UserID: ".$id."\n", FILE_APPEND);
$this->_db->commit();
}catch(PDOException $e){
file_put_contents(DATACHANGE_LOG, date("r")."Error". $e->getMessage()." UserID: ".$id."\n", FILE_APPEND);
if($this->_db->rollback())
header("Location: http://link");
}
header("Location: http://anotherlink");
There is nothing essentially different inside try..catch blocks. And your file writing code should be working the same way as outside, no difference.
The only issue I can think of is irrelevant to try..catch but to exceptions in general: a thrown exception terminates further code execution. Say, if there is an error in $stmt->rollBack(); - no code below will be executed. So, it's better to move a logger at the top of the block.
Related
I'm using CodeIgniter and am trying to execute code in a try/catch block with the idea that errors will stop execution of the code after the error until the catch block is reached, as you would normally think it would work.
However on encountering PHP Errors, the code is continuing. This is causing a database transaction complete command to execute which is .... very bad if there's an error and all of the instructions weren't carried out properly. For example, I have this code which is executed in an ajax request:
// start transaction
$this->db->trans_start();
try {
$this->M_debug->fblog("firstName=" . $triggerOpts->{'firstXXXName'});
$data = array("test_col" => 123);
$this->db->where("id", 4);
$this->db->update("my_table", $data);
// if got this far, process is ok
$status = "process_ok";
// complete transaction
$this->db->trans_complete();
} catch (Exception $ex) {
// output the error
$this->M_debug->logError($ex);
}
In this code, I'm trying to execute a database update as part of a transaction.
My call to $this->M_debug->fblog() is designed to just log a variable to PHP Console, and I've deliberately tried to log a variable that does not exist.
This causes a PHP error, which I guess is a fatal error, and the desired result is that the code after the log commands fails, and the transaction does not complete. However after this error, despite reporting the PHP error in Chrome console, the code keeps right on executing, the database is updated and the transaction is completed. Would appreciate any help in how i could stop this from happening.
Thanks very much, G
EDIT --
As requested heres fblog(), it's simply a Chrome console log request of a variable
public function fblog( $var ) {
ChromePhp::log( $var );
}
Assuming you're using PHP 7.0 or higher, you can catch PHP errors as well as exceptions, however you need to catch Error or the parent Throwable type rather than Exception.
try {
...
} catch (Throwable $ex) {
//this will catch anything, including Errors and Exceptions
}
or catch them separately if you want to do something different for each of them...
try {
...
} catch (Exception $ex) {
//this will catch Exceptions but not errors.
} catch (Error $ex) {
//this will Errors only
}
Note that if you're still only PHP 5.x, the above won't work; you can't catch PHP errors in older PHP versions.
I have to include database connection in some PHP scripts. So I require() first and then put my queries after. If viewed as a single script, it amounts to something like this:
Try {
$connect = new PDO("mysql:host={$DB_host};dbname={$DB_name}; charset=utf8mb4",$DB_user,$DB_pass);
$connect->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
Catch(PDOException $e) {
echo $e->getMessage();
}
// Then I put the queries here
It works, but my question is: is this safe? I've seen in most tutorials that they put all the queries within Try { } curly brackets. And what is the difference between putting the queries within Try { } and putting it after ?
If for whatever reason your query fails the program will crash at the line of code that was executing the query. There may be justification to do this if this a behavior that you desire in your code, for whatever reason.
Without the error handling your program will just break whenever an error is thrown. So unless you specifically need to have the query outside of the try catch (I couldn't guess what for), then you will just be creating trouble for yourself in the future.
If an exception occurs during your query (For instance, if it can't execute the query properly because of a missing quote), the error will not be caught and the execution of your script will halt.
Error handling is usually always preferred when possible. If there is a problem fetching data, inserting data, or simply a typo in your query, you should always have a way to notify a user that an error has occurred (And also, log it for further investigation for yourself.)
SOLUTION: I've been working on the iOS side of it at the same time and must have got the languages switched up. Instead of the $, I put *.
I am trying to get a try{} catch{} working in PHP. My code works when I remove the try{} catch{}. Once I put it back in, it breaks my script. I even tried making it empty in both the try{} catch{}, but it still crashes my script.
try {
}
catch (Exception *e) {
}
Is there a reason the try{} catch{} would cause the script to crash? When I run it in my browser it just shows a white screen.
I even went and made another empty PHP file and put this code in without the if statement. And still, it doesn't work. The page is still white. I had it echo in the try.
Your catch declaration is incorrect.
catch (Exception *e) {
Should be.
catch (Exception $e) {
The inaccurate code would cause a parse error, thus preventing the script from running at all, and producing a white screen.
Maybe possibilities catch is not getting the object values. You should use it as:
try
{
some statement....
}
catch(Exception e)
{
some statement...
}
try{
//PDO CONNECT DB, $db
}catch(PDOException $e){die("ERROR"));}
I have a query user PDO connect to database.
I use try & catch, my question is if my query is error
Do i need to close conncetion before die();?
}catch(PDOException $e){$db="NULL"; die("ERROR"));}
As a matter of fact, you shouldn't die() at all
Until you learn how to use try and catch properly, you shouldn't use this statement. It is not intended for echoing "ERROR". It has totally different purpose.
If you want to echo silly "ERROR" in case of an erroneous query, you have to do it properly.
Namely,
send appropriape HTTP header
log the error to notify a developer of the problem
show whatever error message to the client
have all this stuff done in one place, not repeated for every query
to do this, you have to set up an exception handler:
set_exception_handler('myExceptionHandler');
function myExceptionHandler($e)
{
header('HTTP/1.1 500 Internal Server Error', TRUE, 500);
error_log($e->getMessage().". Trace: ".$e->getTraceAsString());
echo "ERROR";
exit;
}
put this code in your bootstrap/config file and quit wrapping every query into try-catch.
No, it is not necessary in php. When your php process finished, the connection will be closed too.
I need to use transaction for a block of code, it consists of multiple insertions. Is it a good practice to have whole block of code within a try catch block, start transaction before the try..catch block. Then for any exception caught rollback the transactions else commit.
Basic question:
is it bad practice to have whole block of code within a single transaction cycle?
If it is a bad practice what would be a good way to handle this and why?
Here's a block of code:
$con = Propel::getConnection(SomeTablePeer::DATABASE_NAME);
$con->beginTransaction();
try {
$currentRevision = $budgetPeriod->getRevision();
$newRevision = $currentRevision->copy();
$newRevision->setIdclient($client->getIdclient());
$newRevision->setIsLocked(0);
$newRevision->save();
$currentRevision->setEffectiveTo($currentDate);
$currentRevision->save();
$currentRevisionHasCorporateEntities = $currentRevision->getCorporateEntitys();
$newOldCorporateEntitiesRelations = array();
foreach ($currentRevisionHasCorporateEntities as $currentRevisionHasCorporateEntity) {
$newRevisionHasCorporateEntity = $currentRevisionHasCorporateEntity->copy();
$newRevisionHasCorporateEntity->save();
}
// this continues for a while there are a whole list of insertions based on previous insertion and on and on.
}catch (Exception $exc) {
$con->rollback();
$this->getUser()->setFlashError('Error occured! Transaction Failed');
}
Actually, We should focus on smaller transaction boundaries so that we can avoid any locks if occurs in Db but sometimes we need whole block of code to either executed or not, so in that case we hardly have any chances left with us, you need to modularize your code as much as possible.
The thing to be noted here is that how ever big the try block be, we should be able to catch the exceptions thrown by it and take actions accordingly.
But here you have used
catch (Exception $exc)
you will not be able to catch different exceptions. This is helpful to debug and show the correct reason for the exception.
Also if its a transaction, we have to have it in a single try block