How to catch db errors?

I use the code by going through the tutorial by odan


After that added database connectivity in settings.php [ I use Postgres database ]
$settings[‘db’] = [
‘driver’ => ‘pgsql’,
‘host’ => ‘localhost’,
‘port’ => ‘5433’,
‘database’ => ‘test’,
‘username’ => ‘user’,
‘password’ => ‘pass’,
];


container.php was added with
PDO::class => function (ContainerInterface $container) {
$settings = $container->get(‘settings’)[‘db’];

	$host     = $settings['host'];
	$dbname   = $settings['database'];
	$username = $settings['username'];
	$password = $settings['password'];
	$port     = $settings['port'];

	$dsn = "pgsql:host=$host;port=$port;dbname=$dbname";

	return new PDO($dsn, $username, $password);
},

public function insertUser(array $user): array
{
	$username = isset($user[0]["username"]) ? $user[0]["username"] : null;
	$first_name = isset($user[0]['first_name']) ? $user[0]['first_name'] : null;
	$last_name = isset($user[0]['last_name']) ? $user[0]['last_name'] : null;
	$email = isset($user[0]['email']) ? $user[0]['email'] : null;
	
	$db = $this->connection;
	$db->beginTransaction();

	$sql = " Insert into users0 (username, first_name, last_name, email) ";
	$sql = $sql . " values (?, ?, ?, ?) ";

	try
	{
		$statement = $db->prepare($sql);
		$statement->execute([$username, $first_name, $last_name, $email]);
		$db->commit();
    	return $this->customResponse->is201Response('Success');
	}
	catch(PDOException $e)
	{	
		$db->rollBack();
    	return $this->customResponse->is500Response($e->getMessage());
	}
}

It works fine when all data is correct. No issues.
When some error occurs (like a Unique key violation, or check constraint), I want to catch those errors and return an appropriate response to the user. I hope PDOException will catch those errors, which is not catching.

I get only is201Response(‘Success’) even when there is either unique key violation or check constraint violations in the data. Would like to know why the PDOException is not catching those errors?

What should I do to catch those errors?

TIA
Krithika

Try:

try {

} catch (Throwable $t) {

}

Thanks, tj_gumis for your reply.

  1. I tried inserting duplicate values for the username column, which has a unique key constraint.
  2. There is no table name with users0, which has been used in the query. The correct name was users only.
    In both cases, I get a ‘success’ message only, with your suggestionof catching Throwable also.
    I already tried catching PDOException, Exception.

Than try this way:

// 1) you don't need transaction for single table insert
// 2) user at this point should be already validated
public function insertUser(array $user): string
{
    $sql = "INSERT INTO users0 (username, first_name, last_name, email)  VALUES (?, ?, ?, ?) ";
    
    $statement = $this->connection->prepare($sql);
    $statement->execute($user));

    $errors = $this->connection->errorInfo();
    if (!empty($errors)) {
        // 1) array index by your choice (look what info is given)
        // 2) catch this exception there where insertUser() was called
        throw new MyException($errors[0]);
    } 

    return PDO::lastInsertId();       
}

In order to enable exceptions, you need to pass this to the PDO constructor as options parameter:

$options = [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
];

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

https://www.php.net/manual/en/pdo.error-handling.php

Thanks tj_gumis and Odan,
Odan’s solution worked.

tj_gumis: This is only a sample code. In project development, there will be multi-table insert / update / delete, where we need transactions and also need to catch any / all exceptions.
Thanks again.

Hello,

If I declare a new setting in settings.php, can I access that value in the UserCreateAction.php file?

My declaration in the settings.php file is like this
$settings[‘version’] = [
[php_version’] => ‘5.0’
];

I want to access the above value in the UserCreateAction.php file, like this
if ($settings[‘version’][‘php_version’] != $data[0][‘client_ver’]) {

}

I tried including the settings.php file in UserCreateAction.php file, like
include DIR . ‘/…/…/config/settings.php’;

and get the following error
Notice : Undefined variable: settings in E:\xampp\htdocs\baseten\src\Action\UserCreateAction.php on line 29

Any suggestion?

To access the config within an object, you need to add a “Config” class to your project that holds the config keys and values. Then you are able to inject that object via the constructor. Example

Thanks Odan,
That solution solved this issue.

1 Like