getting more informative log output in PHP on webhosting PDO - php

I have been developing complex platform, on which to build latter. I have reached the point when it works on mine lamp, but not when via webhosting. One of mine function designed to log the variables to the database during operation keeps sending just a petty
Fatal error: in /home/.../asi/kluckaSpolocne.php on line 51
This points to the exception of execute statement:
throw new \PDOException($e->getMessage(), (int)$e->getCode());
the code in question:
//echo "\n Spolocne ";
//require 'ochrana.php';
// include 'databazaCitaj.php';
$dbuzyvatel = "mine login";
$dbheslo = "mine password";
//$charset = 'utf8mb4';
$opt = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
try {
$databaza = new PDO("mysql:host=localhost;dbname=mine_database", $dbuzyvatel, $dbheslo);
$databaza->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (\PDOException $e) {
throw new \PDOException($e->getMessage(), (int)$e->getCode());
}
# $preloz = $databaza->prepare('select ? from preklady where jazyk=?');
$GLOBALS['nová']=false;
$DlzkaVystupu=1;
$IC=0;
$Hesla=json_encode(array(1,1));
$HlavnýÚčel=0;
$Kolá=array(0);
$Hlasenia['Premenna']=' ';
$Hlasenia['Text']=' ';
$Hlasenia['Cislo']=1;
$Hlasenia['JS']='[0]';
$Hlasenia['Kdo']=0;
$Hlasenia['Vlastnosti']='[0]';
//print_r($Hlasenia);
/*$hlásenie=$databaza->prepare('insert into Hlásenia (Premenná, Text)
values (:Premenna, :Text)');//*/
$hlásenie=$databaza->prepare('insert into Hlásenia (Premenná, Text, Cislo, JS, Kdo, Vlastnosti)
values (:Premenna, :Text, :Cislo, :JS, :Kdo, :Vlastnosti)');//*/
$hlásenie->bindParam(':Premenna', $Hlasenia['Premenna']);
$hlásenie->bindParam(':Text', $Hlasenia['Text']);
$hlásenie->bindParam(':Cislo', $Hlasenia['Cislo']);
$hlásenie->bindParam(':JS', $Hlasenia['JS']);
$hlásenie->bindParam(':Kdo', $Hlasenia['Kdo']);
$hlásenie->bindParam(':Vlastnosti', $Hlasenia['Vlastnosti']);//*/
// print_r($hlásenie);
try { $hlásenie->execute();
} catch (\PDOException $e) {
throw new \PDOException($e->getMessage(), (int)$e->getCode());
}//*/
Any idea about how to get some useful info about what is wrong?

Looks like it's your "function designed to log the variables" is messing with the error message.
Make it this way:
set_exception_handler(function ($e)
{
error_log($e);
http_response_code(500);
if (ini_get('display_errors')) {
echo $e;
} else {
echo "<h1>500 Internal Server Error</h1>
An internal server error has been occurred.<br>
Please try again later.";
}
});
It will catch every exception and log it into web-server's error log.
It's part of a complete error handling solution I wrote.

Related

Catch exception while mysql die - slim and prevent log to php_error log in that case

Hi I have the following code :
try {
$sth = $this->container->db->prepare("select x from table");
$sth->execute();
$result = $sth->fetchAll(PDO::FETCH_ASSOC);
return $result;
} catch (\PDOException $e) {
throw new ServerException("Could not get data");
} catch (\Exception $e) {
return false;
}
using slim 3 with wamp
the problem is when I point to the API(polling every 1 second) I got the following error:
Fatal error: Call to a member function prepare() on boolean in /
2 issues : it throws an error to the client
and it throws an error in php_error.log under wamp and the file becomes bigger
how can I prevent and catch those errors
PDO class:
public function getConnection($dsn, $username, $password) {
$conn = null;
try {
$conn = new PDO($dsn, $username, $password);
//Set common attributes
$conn->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
return $conn;
} catch (PDOException $e) {
return false;
//TODO: flag to disable errors?
throw $e;
}
catch(Exception $e) {
die();
//TODO: flag to disable errors?
throw $e;
}
}
Like many learners, you are taking this matter upside down
You should never actually catch an exception like this.
it throws an error to the client
Disable it for the whole site on the live server. There should be not a single PHP error message shown to the user, no matter if it's PHP exception or a filesystem error. Set display_errors to a negative value and forget this matter for all.
how can I prevent and catch those errors
Again, you should never do anything like this, bluntly catching every error and just dismissing it. It's like using the notorious # operator
it throws an error in php_error.log under wamp and the file becomes bigger
Ok, only this one makes sense. There are two possible solutions:
The best one: configure your mysql server properly so it wouldn't die under such a light load like 1 RPS.
Okay, what you actually want but I still don't recommend as it never pays to sweep the dirt under the rug: catch the exception, then verify if it's one you expect, then do something (i.e. try to reconnect after a short timeout), but re-throw the exception otherwise so you will have an idea when something else would go wrong. For this purpose you should add a condition in the try..catch block that should verify the error, handle it if it's one that you expect or just throw it again otherwise.
Of course, in order to catch a PDOException you have to enable it for PDO.
1) In Slim you should use the container (service factory) to build the PDO object. Example:
$container['db'] = function (Container $container) {
$settings = $container->get('settings');
$host = $settings['db']['host'];
$dbname = $settings['db']['database'];
$username = $settings['db']['username'];
$password = $settings['db']['password'];
$charset = $settings['db']['charset'];
$collate = $settings['db']['collate'];
$dsn = "mysql:host=$host;dbname=$dbname;charset=$charset";
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_PERSISTENT => false,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES $charset COLLATE $collate"
];
return new PDO($dsn, $username, $password, $options);
};
2) You must set the PDO options into the constructor to make it work. Example:
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
];
$pdo = new PDO($dsn, $username, $password, $options);

How do I ensure all exceptions in this DB transaction are caught?

I use Yii and recently started using Transactions with try / catch blocks.
Here's how the code looks right now:
$dbConnection = Yii::app()->db();
try {
$transaction = $dbConnection->beginTransaction();
$dbConnection->createCommand("SELECT * from table_1")
->queryAll();
$transaction->commit();
} catch (Exception $ex) {
$transaction->rollback();
}
Suppose there's an exception with the DB (it's come up while unit-testing), I'm unable to rollback because the PHP dies with a fatal $transaction undefined error.
I'd rather not include isset() checks everywhere..
Is there a simpler way to make this work?
You can check if the exception is an instance of CDbException
$dbConnection = Yii::app()->db();
try {
$transaction = $dbConnection->beginTransaction();
$dbConnection->createCommand("SELECT * from table_1")
->queryAll();
$transaction->commit();
} catch (Exception $ex) {
if ($ex instanceof CDbException)
{
// handle CDBException
// ...
}
$transaction->rollback();
}

PHP PDO - What needs to try catch?

I'm using PHP and PDO. Now I want to build a kind of log when things go wrong. What can go wrong with PDO?
Right now I have these tests:
Connection test
try {
$this->pdo = new PDO($dsn, $credentials['user'], $credentials['pass'], $options);
} catch(Exception $e) {
$this->file->put( date('Y-m-d') . '.txt', 'log', 'Database error');
}
Execute test
try {
$stmt->execute();
} catch(Exception $e) {
$this->error->log('SQL', 'query error');
}
Any more tests that are good?
You do not log your exception message in your logs. I suggest you to do something like this into your catch :
$this->error->log('SQL', $e . PHP_EOL);
This will give you more understandable and readable logs.
Regarding the exceptions to catch with PDO, you may read that post : How to handle PDO exceptions

fatfree SQL error handling

If, for whatever reason, there is an error in creation of an entry using the mapper I get an error.
I'd like to do a custom notification and fail gracefully like so...
try {
$request->save();
} catch (Exception $e) {
$this->utils->errorNotify($f3,'could not create a request entry',http_build_query($_POST));
return null;
}
is this possible with F3?
\DB\SQL is a subclass of PDO so it can throw catchable PDO exceptions. Since these are disabled by default, you need to enable them first. This can be done in 2 different ways:
at instantiation time, for all transactions:
$db = new \DB\SQL($dsn, $user, $pwd, array( \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION ));
later on in the code, on a per-transaction basis:
$db->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
Once PDO exceptions are enabled, just catch them as other exceptions:
try {
$db->exec('INSERT INTO mytable(id) VALUES(?)','duplicate_id');
} catch(\PDOException $e) {
$err=$e->errorInfo;
//$err[0] contains the error code (23000)
//$err[2] contains the driver specific error message (PRIMARY KEY must be unique)
}
This also works with DB mappers, since they rely on the same DB\SQL class:
$db=new \DB\SQL($dsn,$user,$pwd,array(\PDO::ATTR_ERRMODE=>\PDO::ERRMODE_EXCEPTION));
$mytable=new \DB\SQL\Mapper($db,'mytable');
try {
$mytable->id='duplicate_id';
$mytable->save();//this will throw an exception
} catch(\PDOException $e) {
$err=$e->errorInfo;
echo $err[2];//PRIMARY KEY must be unique
}

php pdo catching connection exception with custom exception handler

What im trying to achieve here , is when the pdo connection throws an exception , my custom exception handler takes the message and passes it on so i can catch it with my custom exception handler.
try {
$mysqli = new PDO('mysql:host='.THOST.';dbname='.TDB.'', TUSER, TPASS);
}
catch (PDOException $e) {
$a = $e->getMessage();
throw new customException ( "Failed to connect to MySQL:". $a );
die();
}
catch (customException $e){
echo $e->errorMessage();
}
BUT it returns this error :
Fatal error: Uncaught exception 'customException' with message ......
Wrap it in another try-catch block.
try {
try {
$mysqli = new PDO('mysql:host='.THOST.';dbname='.TDB.'', TUSER, TPASS);
} catch(PDOException $e) {
$a = $e->getMessage();
throw new customException ( "Failed to connect to MySQL:". $a );
}
} catch(customException $e) {
echo $e->errorMessage();
// Do what you want
}
You are confusing custom exception handler with custom exception class. You need the former one and the other answer is wrong.
Explanation.
In your application code you have to writing one single line only:
$pdo = new PDO('mysql:host='.THOST.';dbname='.TDB.'', TUSER, TPASS);
without multiple tries and stuff. Just the code you need to run.
While all the handling logic goes into handler

Categories