3
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?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • 9
    You shouldn't be displaying errors in a production environment. You should be suppressing and/or catching errors and sending yourself an alert if anything. – skrilled May 09 '14 at 17:59
  • `// self::$dbinstance->setAttribute(PDO::ATTR_ERRMODE....` – Funk Forty Niner May 09 '14 at 18:11
  • i'm already doing the same – Muhammad Haseeb Khan May 09 '14 at 18:15
  • it will behave same like turning the error display off. then how would i know when host not responding – Muhammad Haseeb Khan May 09 '14 at 18:19
  • Have the connection in an if statement or create a,custom error handler – Daryl Gill May 09 '14 at 18:33
  • Yes, it does. Step 1) Do not mindlessly copy everything you see. Step 2) Read my answer and evaluate if it works for you – MonkeyZeus May 09 '14 at 18:48
  • 1
    @tympaniplayer how i can throw, as it is an uncaught exception and it is not being captured in catch block – Muhammad Haseeb Khan May 09 '14 at 18:55
  • @tympaniplayer because it is **original message** what a *programmer* needs, not some custom rubbish. Even though there are no programmers among PHP users, it doesn't matter things have to be done wrong way. – Your Common Sense May 09 '14 at 18:58
  • 1
    Normally I would agree @YourCommonSense, but it is tossing back the Username and Password. Thats a problem isn't it? – tympaniplayer May 09 '14 at 18:59
  • @tympaniplayer this trifle inconvenience is easily solvable. But it doesn't really matter if you handle errors properly - so, I wouldn't bother with hiding password at all. – Your Common Sense May 09 '14 at 19:00
  • @YourCommonSense: Well then please show OP how to easily solve that inconvenience, and handle errors properly :) – tympaniplayer May 09 '14 at 19:02
  • @YourCommonSense "is easily solvable"? that what i'm looking from last one hour. is turning error off is the only solution? – Muhammad Haseeb Khan May 09 '14 at 19:02
  • 1
    Tell me first, do you understand the importance of the stack trace? Or all your idea of handling errors is just like echo "Errors".$e->getMessage();? – Your Common Sense May 09 '14 at 19:03
  • Usually in web applications errors are being logged to logfiles/log collectors. This would mean that right now the webservers are seeded with logfiles containing the database credentials. One single bug/exploit in the Apache/nginx webserver would cause the database credentials to be exposed for millions of websites LOL... – Pieterjan Apr 17 '21 at 12:50

4 Answers4

10

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • 3
    That's good answer (or even excellent one) but only to the point of the practical implementation. Also, it misses the point in question, which is: His error is *uncaught*. There is no point in any rant on error handling and catching if none of them works. To help you making it proper, let me hint you with 2 things the poor OP is looking for: 1. *namespaces*. 2. One can get trace as an *array*. And manually create whatever output they want, including whatever data they want. – Your Common Sense May 10 '14 at 04:41
  • 3
    Also, it would be nice if you explain to the OP the importance of the stack trace, which is absolutely indispensable in any application that is slightly more complex than usual one-page spaghetti. – Your Common Sense May 10 '14 at 04:52
  • Using `register_shutdown_function` helped guided through http://stackoverflow.com/questions/277224/how-do-i-catch-a-php-fatal-error. as you have most relevant infomation so i'll accept is as answer – Muhammad Haseeb Khan May 10 '14 at 07:31
  • Now you're gonna email the database credentials to yourself. That's even worse than writing them to a log file – Pieterjan Apr 17 '21 at 13:04
  • @Pieterjan You misunderstand.This is meant as a general solution, not only about the password case. In the first part of the answer I talk about not seeing the password on *screen* (you just added logs to the equation) and in the second I expose how catching exceptions generally works. Sending the password in a mail is better than exposing it on screen, yes, but there could be any type of handling of the exception there, including writing in a log. – Félix Adriyel Gagnon-Grenier Apr 17 '21 at 15:04
6

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Your Common Sense
  • 156,878
  • 40
  • 214
  • 345
1

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Shankar Narayana Damodaran
  • 68,075
  • 43
  • 96
  • 126
-3

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');
}
?>
MonkeyZeus
  • 20,375
  • 4
  • 36
  • 77