7

I have a PHP script with two deliberate typo mistakes in the statement for an SQL query:

try
{
 $stmt = $dbh->prepare("SELECT COUNT(*) FROM Product WHERE non-existent_column=?");
 $stmt->blindValue(1, $id, PDO::PARAM_INT);
 $stmt->execute();
 $row = $stmt->fetchColumn();
}
catch(PDOException $err)
{
 var_dump($err->getMessage());
 var_dump($dbh->errorInfo());
}

However, the script does not catch the error even after setting attribute to PDO::ERRMODE_EXCEPTION. What am I missing here?

UPDATE:

This is the full script. The second typo blindValue has been reverted back. The error remains uncaught:

<?php

$user= "user";
$password = "password";
$dsn = "mysql:dbname=Catalogue;host=localhost";
$dbh = new PDO($dsn, $user, $password);
$dbh->setAttribute(PDO::ERRMODE_EXCEPTION); 
$id = 1000;

try
{
 $stmt = $dbh->prepare("SELECT COUNT(*) FROM Product WHERE non-existent_column=?");
 $stmt->bindValue(1, $id, PDO::PARAM_INT);
 $stmt->execute();
 $row = $stmt->fetchColumn();
}
catch(PDOException $err)
{
 echo "caught";
 var_dump($err->getMessage());
 var_dump($dbh->errorInfo());
 exit();
}

var_dump($stmt);
var_dump($row);
echo "uncaught";
exit();

?>
Charles
  • 50,943
  • 13
  • 104
  • 142
Question Overflow
  • 10,925
  • 18
  • 72
  • 110
  • 1
    If the exception ends up with the default error handler, can you show the message? Also you do have a typo in `->blindValue`. That would lead to a fatal error, not an exception. – mario Nov 18 '11 at 09:19
  • @mario, you mean the default as in `$err` added above? I added that one too, no error message. The script skips through the entire catch block. – Question Overflow Nov 18 '11 at 09:22
  • @mario, yes, that is the second typo. First one is the non-existent column. – Question Overflow Nov 18 '11 at 09:24
  • 1
    If you do get the error message `PHP Fatal error: Call to undefined method PDOStatement::blindValue()` then that can't be caught with a `try/catch` declaration. That's not an exception, is an interpreter error. – mario Nov 18 '11 at 09:27
  • @mario, I see.. but even if I correct this second error, the first error also couldn't be caught. – Question Overflow Nov 18 '11 at 09:30
  • You still need to tell what exactly that message says. The full message, no excerpts. – mario Nov 18 '11 at 09:32
  • @mario, I got no message from both `getMessage` and `errorInfo`. And no fatal error also. – Question Overflow Nov 18 '11 at 09:33
  • So what you are actually saying is that the query seemingly succeeds, and thus you get no message/exception. What does `var_dump($stmt)` and `$row` say? Can you also test with just `->query("SELECT garbage FROM wrong");` in place of the `prepare/execute`? – mario Nov 18 '11 at 09:38
  • Please give us a _complete_, self-contained example, see http://sscce.org/ – VolkerK Nov 18 '11 at 09:43
  • I am not sure whether the query succeeds or not. This is what I get for `$stmt=object(PDOStatement)#3 (1) { ["queryString"]=> string(101) "SELECT COUNT(*) FROM Product WHERE non-existent_column=?" }` and for `$row=bool(false)`. – Question Overflow Nov 18 '11 at 09:47
  • @mario, I tried `->query("SELECT garbage FROM wrong");`. It didn't reach pass the catch block. I am not sure whether it entered catch block since no error message is generated and echo string doesn't produce anything too. – Question Overflow Nov 18 '11 at 09:57
  • possible duplicate of [How to squeeze error message out of PDO?](http://stackoverflow.com/questions/3726505/how-to-squeeze-error-message-out-of-pdo) – Your Common Sense Nov 18 '11 at 10:12
  • @ Col. Shrapnel, I read your post. Pekka says PDO::ERRMODE_EXCEPTION must work, but it didn't in my case. – Question Overflow Nov 18 '11 at 10:21

3 Answers3

13

Your call to setAttribute() lacks the first parameter:

$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 

If you didn't get a

Warning: PDO::setAttribute() expects exactly 2 parameters, 1 given

your error_reporting level is too low for a development server and/or you didn't keep an eye on the error log or didn't set display_errors=On (which ever you prefer; I prefer the error log over display_errors).


edit: please try

<?php
echo 'php version: ', phpversion(), "\n";

try {
    $dbh = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'localonly', 'localonly');  
    echo 'client version: ', $dbh->getAttribute(PDO::ATTR_CLIENT_VERSION), "\n";
    echo 'server version: ', $dbh->getAttribute(PDO::ATTR_SERVER_VERSION), "\n";
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
}
catch(PDOException $err) {
    var_dump($err->getMessage());
    die('...');
}

$id = 'foo';

try
{
    $stmt = $dbh->prepare("SELECT COUNT(*) FROM Product WHERE `non-existent_column`=?");
    $stmt->bindValue(1, $id, PDO::PARAM_INT);
    $stmt->execute();
    $row = $stmt->fetchColumn();
}
catch(PDOException $err)
{
    var_dump($err->getMessage());
    var_dump($dbh->errorInfo());
    die('....');
}

echo 'done.';

printed on my machine

php version: 5.3.5
client version: mysqlnd 5.0.7-dev - 091210 - $Revision: 304625 $
server version: 5.5.8
string(94) "SQLSTATE[42S22]: Column not found: 1054 Unknown column 'non-existent_column' in 'where clause'"
array(3) {
  [0]=>
  string(5) "42S22"
  [1]=>
  int(1054)
  [2]=>
  string(54) "Unknown column 'non-existent_column' in 'where clause'"
}
....
VolkerK
  • 95,432
  • 20
  • 163
  • 226
  • Works fine on my machine also. This is the right answer, because the only reason why an exception wouldn't be caught (when forced) is if PDO isn't in exception mode. This properly sets it in exception mode and works fine on my copy. +1 for a proper and detailed answer. – N.B. Nov 18 '11 at 10:31
  • It works fine for me too. But I couldn't find where I had gone wrong with my script. Anyway, thanks. I will look into it further. – Question Overflow Nov 18 '11 at 10:42
3
$stmt->blindValue(1, $id, PDO::PARAM_INT);

This should be $stmt->bindValue(1, $id, PDO::PARAM_INT);

You cannot catch Fatal Errors such as calling an undefined function/method.

ThiefMaster
  • 310,957
  • 84
  • 592
  • 636
-2

I experienced this and realized it was my PHP configuration file.

xdebug.show_exception_trace = 1

Exceptions will always appear if this is true.