-2

My website sends an XMLHttpRequest to this PHP script:

<?php
if(isset($_POST))
{
    require ('../../PDOConnect.php');   
    try
    {
        $insert = $pdo->prepare("INSERT INTO priorities 
            employeeID, WorkOrderNumber
            VALUES (?,?)");
        $insert->bindValue(1,$_POST['employeeID'],PDO::PARAM_INT);
        $insert->bindValue(2,$_POST['WorkOrderNumber'],PDO::PARAM_INT);
        $insert->execute();
        echo "try";
    }
    catch(Exception $e)
    {
        echo "catch";
        echo $e;
    }
}
?>

At this point, the priorities table does not exist. I'm expecting the XMLHttpRequest's status to be 500 because the query obviously will always fail. PDO does log the error because PDOConnect contains

$pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING);

but I get a 200, not a 500. I'm new to PDO. When I was using MySQLi prepared statements, I would get a 500 back from failed PHP scripts, but PDO acts differently. I want the client to know that the query failed, rather than getting a 200 back and thinking that everything went okay. I get the same results with and without try and catch. Am I failing to understand how PDO works? Do I need to change a PDO setting?

Edit: I added echo "try"; and echo "catch";. The client's responseText is always "try", never "catch". It seems that the catch statement doesn't run. Why is that?

My PDOConnect.php file contains:

<?php
$options =
[
        PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING,
];
        $pdo = new PDO('mysql:host=localhost;dbname=mydb;charset=utf8mb4','root','mypassword',$options);
        $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING);
?>
aswine
  • 179
  • 11
  • 1
    The 200 is because the AJAX request succeeded - it reached your PHP script. If you want the PHP script to return the 500 error via AJAX you have to capture that and do what you want with it. Your PHP script worked properly too, it delivered the 500 because the query was bad. – Jay Blanchard Jan 23 '18 at 17:48

2 Answers2

1

Make sure the PDO options are set correctly. It's importand to set the PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION option via the $option parameter of the PDO constructor. Don't set this option via setAttribute(), it's pointless.

$options = [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_PERSISTENT => false,
    PDO::ATTR_EMULATE_PREPARES => false,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES $charset COLLATE $collate"
];

$pdo = new PDO($dsn, $username, $password, $options);

Then handle the Exception and send the 500 http error code:

try {
    // do something
} catch(Exception $ex) {
    header('500 Internal Server Error', true, 500);
    echo $ex->getMessage();
}
odan
  • 4,757
  • 5
  • 20
  • 49
  • @aswine See [How to send 500 Internal Server Error error from a PHP script](https://stackoverflow.com/questions/4162223/how-to-send-500-internal-server-error-error-from-a-php-script). Maybe try Daniel's answer without the `echo`. – Mikey Jan 23 '18 at 18:42
  • @Mikey See my edit. The catch statement doesn't run. – aswine Jan 23 '18 at 18:49
  • This is not the "only" point of my answer. It's important to enable the `PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION` option via the constructor. Please show us the content of `PDOConnect.php` – odan Jan 23 '18 at 18:57
  • @DanielO. I understand. When I said "I just tried that.", I meant setting the error mode via the constructor. I edited my question to include the contents of `PDOConnect.php`. – aswine Jan 23 '18 at 19:06
  • Ok thanks. You have set the option to `PDO::ERRMODE_WARNING` This is not the same. Please set this value to `PDO::ERRMODE_EXCEPTION`. – odan Jan 23 '18 at 19:09
  • Same results using `PDO::ERRMODE_EXCEPTION`. I'm pretty sure `PDO::ERRMODE_WARNING` is more strict. – aswine Jan 23 '18 at 19:13
  • `PDO::ERRMODE_WARNING` will cause PDO to throw an error of level E_WARNING instead of an exception. http://php.net/manual/en/pdo.error-handling.php – odan Jan 23 '18 at 19:16
0

You can also try this in your try...catch syntax to know what error you are getting in your PDO query.

<?php
try {
    //pdo query
}
catch(PDOException $e) {
    echo 'Exception -> ';
    var_dump($e->getMessage());
}

Then note that 200 response means that your Ajax request succeeded. If you're getting a 500 response then check your configuration. The 500 Internal Server Error is a very general HTTP status code. It means something has gone wrong on the website and webserver is unable to specify what exactly, thus failing in fulfilling the request made by the client. This is not related to client and the fault is in the webpage/website requested that resides on server. This status code can be considered as a ‘catch-all’ server error of Web server.

OmniPotens
  • 1,125
  • 13
  • 30