Laravel postgresql error handling - php

I'm new to laravel and I couldn't find an answer to the problem in the documentation nor google. So here it is:
I have to use a vpn connection to connect to the postgresql database. If I'n not connected laravel gives me the following error:
SQLSTATE[08006] [7] could not connect to server: Connection timed
out.....
How do I tell laravel to ignore that error and instead just return a message "no connection"?
$export = DB::connection('pgsql')->select("SOME SQL");
I tried the "#" before the DB, but that doesn't seem to do the trick.

Add this to your routes.php (top of it) or your start.php:
App::error(function(\Exception $e)
{
return "Error handled!";
});
And try again:
$export = DB::connection('pgsql')->select("SOME SQL");
It will catch the error and now you can do whatever you need with it.
If you return null from that error handler, Laravel will catch the error and do what it is doing now.

Related

WordPress database error INSERT command denied to user 'readonly'

I'm working with Wordpress and PHP. We had an issue in which our w writer db became our reader r db during a fail over in the database cluster. This cause the production site to break. Currently, I'm trying to prevent the site from crashing do to this.
I get the following error from WP Engine when the database is trying to insert data into a table:
WordPress database error INSERT command denied to user
'readonly'#'xx.xxx.xx.xx' for table 'responses' for query INSERT INTO
responses (uid, data) VALUES
The error is raise from the following function:
<?php
namespace StatCollector;
function drools_request($data, $uid) {
try {
$db = _get_db();
$insertion = $db->insert("requests", [
"uid" => $uid,
"data" => json_encode($data),
]);
if($insertion === false) {
throw new \Exception('Error writing to the database: ' . $db->last_error);
}
}
catch(\Exception $e)
{
echo 'Error writing to the database: ', $e->getMessage(), "\n";
}
}
When the database become --read-only this shouldn't stop the site to work. Why isn't error handling working in this case. Does this mean that to error handle this I need to catch an Error? Why isn't the error handling working here?
[Not sure this works, but it is too long for a comment]
You didn't mention your back-end database, so I bet it is MySQL because you mentioned Wordpress.
You can try to instruct mysql to throw exceptions, like this:
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
class.mysqli-sql-exception
I wouldn't advice to do that in the core of wordpress itself, but you can try calling it before executing your try/catch.
Edit: Some people advice MYSQLI_REPORT_ALL instead of MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT. Give it a try and see what works best in your situation.

How to throw error when issue with mongoDB and PHP connection?

In php and mysql we use mysqli_error(connection); to show error but how to show error while php mongoDB connection goes wrong. $m = new MongoClient();
please help..!
Use the MongoConnectionException class..
This exception gets thrown when you have connection issues.

Laravel 5.1 - Checking a Database Connection

I am trying to check if a database is connected in Laravel.
I've looked around the documentation and can't find anything. The closest thing I've found is this, but this doesn't solve my problem.
I have three instances of MySQL that are set up on different machines. Below is a simplified version of what I am trying to achieve.
If database 1 is connected, save data to it
If database 1 is not connected, check if database 2 is connected
If database 2 is connected save data to it
If database 2 is not connected, check if database 3 is connected
If database 3 is connected, save data to it
To be clear, is there a way to check that a database is connected in Laravel 5.1?
Try just getting the underlying PDO instance. If that fails, then Laravel was unable to connect to the database!
use Illuminate\Support\Facades\DB;
// Test database connection
try {
DB::connection()->getPdo();
} catch (\Exception $e) {
die("Could not connect to the database. Please check your configuration. error:" . $e );
}
You can use alexw's solution with the Artisan. Run following commands in the command line.
php artisan tinker
DB::connection()->getPdo();
If connection is OK, you should see
CONNECTION_STATUS: "Connection OK; waiting to send.",
near the end of the response.
You can use this, in a controller method or in an inline function of a route:
use Illuminate\Support\Facades\DB;
//....
try {
DB::connection()->getPdo();
if(DB::connection()->getDatabaseName()){
echo "Yes! Successfully connected to the DB: " . DB::connection()->getDatabaseName();
}else{
die("Could not find the database. Please check your configuration.");
}
} catch (\Exception $e) {
die("Could not open connection to database server. Please check your configuration.");
}
You can also run this:
php artisan migrate:status
It makes a db connection connection to get migrations from migrations table. It'll throw an exception if the connection fails.
You can use this query for checking database connection in laravel:
use Illuminate\Support\Facades\DB;
// ...
$pdo = DB::connection()->getPdo();
if($pdo)
{
echo "Connected successfully to database ".DB::connection()->getDatabaseName();
} else {
echo "You are not connected to database";
}
For more information, you can check out this page https://laravel.com/docs/5.0/database.
I don't know if this worked in that version of laravel, but at least on newer ones you can run
php artisan db
and if your app can access the database then you should see a cli repl for it, for postgres you will see a psql instance
Another Approach:
When Laravel tries to connect to database, if the connection fails or if it finds any errors it will return a PDOException error. We can catch this error and redirect the action
Add the following code in the app/filtes.php file.
App::error(function(PDOException $exception)
{
Log::error("Error connecting to database: ".$exception->getMessage());
return "Error connecting to database";
});
Hope this is helpful.

Uncaught PDOException reveals username and password

try {
self::$dbinstance = new PDO(
"mysql:host=$c[host];dbname=$c[dbname]", $c['user'], $c['password']
);
self::$dbinstance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e) {
echo "Errors" . $e->getMessage();
}
In the above code, if PDO fails to connect to the host, a fatal error reveals the username and password.
Uncaught exception 'PDOException' with message 'SQLSTATE[HY000] [2003]
Can't connect to MySQL server on '172.25.102.65' (10060)' in
D:\xampp\htdocs\mytest\wh_client_2.1\classes\importmodule-class.php:33 Stack trace: #0
D:\xampp\htdocs\mytest\wh_client_2.1\classes\importmodule-class.php(33): PDO-
>__construct('mysql:host=172....', 'host', 'password') #1
One possible way is to turn the display_error=0 off in php.ini, but this way I won't able to know that when my host is not responding.
Is there a way I can modify the error message?
There is a difference between error handling and error reporting.
Error handling is the process of preventing your end users to see any stack trace, vital information or automatically generated error messages. It can also modify the way your script runs by using a try catch block.
Error reporting defines which information will be reported by a given script.
To handle errors properly, I think that ini_set('display_errors',0); is the better approach. You do not want any error message displaying on the screen.
However, I want to have all possible information on errors, so I use error_reporting(E_ALL);.
Errors are written in a file, error_log, which usually resides at the same level as your index.php (or any PHP file called directly). You can also access it from your cPanel.
Your error is probably uncaught because your code is in a namespace, whereas you want to catch the global namespace PDOException. Use a \ to indicate your script you're looking for the global PDOException. Once you catch your error, you can echo the content you want, using the normal methods of the PDOException class.
try {
$db = new PDO (/*connection infos*/);
}
catch (\PDOException $e) {
switch ($e->errorCode()) {
case 'HY000':
// Or whatever error you are looking for
// here it's the general error code
mail('your#email.com','connection problem',$e->getTraceAsString());
$db = new PDO (/*rollback connection infos of a local database*/);
break;
}
}
That would send you a mail, containing the trace of the error, preventing your user from seeing it while telling you something is wrong.
Here is the reference for the error codes returned by PDO statements.
When your host is not responding you will know all right - your host will stop responding. Then you have to peek into the error log and find the error message with the particular error.
So, just keep with display_errors=0 as it's a must-have in a production environment anyway.
No, don't try to throw the exception as it will spit out such critical information... Handle them with some appropriate custom error messages and handle those exceptions inside your custom logging functions...
You must be doing something similar to this...
<?php
try {
$db = new PDO('mysql:host=localhost;dbname=testdb;charset=utf8', 'uname', 'pass');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$db->query('bla bla bla bla'); //<---- This will definitely fail!!!!
} catch(PDOException $ex) {
echo "An error occurred!";
file_put_contents('somefile.txt', $ex->getMessage(), FILE_APPEND);
}
As you can see, the above query is indeed going to fail. So the end user will be seeing just An error occurred! message, but the error will be logged to your somefile.txt file.
You can do something like this:
<?php
// connect
try
{
$dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass);
}
catch (PDOException $e)
{
$dbh = NULL;
}
// check if connected
if($dbh)
{
// run queries
}
else
{
die('Oops! Our server has encountered an error, please try again later');
}
?>

Laravel Remote/SSH catch SSH2 Exception

When im attempting to deploy things using laravel 4.1's SSH/Remote classes occasionally i get this exception
[2014-01-03 18:26:21] production.ERROR: exception 'ErrorException' with message 'Connection closed by server' in /home/{user}/{location}/deploy/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php:918
I was wondering if there is a way to detect if it has failed to connect in order to attempt the connection again and or multiple times?
Any ideas?
Laravel uses phpseclib for its SSH library. On connection failure, phpseclib executes user_error('Connection closed by server'); (see Net/SSH2.php, line ~911). Laravel has a global error handler that picks this up, and logs it (as you saw in your question).
Unfortunately, phpseclib triggers errors, instead of throwing exceptions. If they were exceptions, you could add a new condition to Laravel's error handling:
App::error(function(Exception $exception){
Log::error($exception);
if($exception instanceof PHPSecLibException){
// Let's handle this
}
});
This definitely would be the "right way" to do it, but these aren't true exceptions (they're generic Laravel exceptions that are generated on your behalf when errors are triggered).
Luckily, Laravel translates errors into exceptions on your behalf. See src/Illuminate/Exception/Handler.php (lines ~129-135). So we could just add a conditional based on the info you do have:
App::error(function(Exception $exception){
Log::error($exception);
if(($exception->getMessage() == "Connection closed by server") &&
($exception->getFile() == "/home/{user}/{location}/deploy/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php")){
// Let's handle this
}
});
Take a look at the Exception methods available.

Categories