Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Lock] PDOStore checks for wrong error code in PDOException for MySQL #54091

Closed
edomato opened this issue Feb 27, 2024 · 0 comments
Closed

[Lock] PDOStore checks for wrong error code in PDOException for MySQL #54091

edomato opened this issue Feb 27, 2024 · 0 comments

Comments

@edomato
Copy link
Contributor

edomato commented Feb 27, 2024

Symfony version(s) affected

5.4 and above

Description

The isTableMissing() method checks for the error code 1146 for MySQL when the table used to store the locks doesn't exists, but the code in PDOException is "42S02" for that server.

PHP documentation says that for the PDOException, the code is the SQLSTATE error code.

The stacktrace that PHP throws is:

PHP Fatal error:  Uncaught PDOException: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'testdb.lock_keys' doesn't exist in /app/vendor/symfony/lock/Store/PdoStore.php:140
Stack trace:
#0 /app/vendor/symfony/lock/Store/PdoStore.php(140): PDOStatement->execute()
#1 /app/vendor/symfony/lock/Store/PdoStore.php(117): Symfony\Component\Lock\Store\PdoStore->putOffExpiration()
#2 /app/vendor/symfony/lock/Lock.php(85): Symfony\Component\Lock\Store\PdoStore->save()
#3 /app/lock_test.php(11): Symfony\Component\Lock\Lock->acquire()
#4 {main}

Next Symfony\Component\Lock\Exception\LockAcquiringException: Failed to acquire the "test-lock" lock. in /app/vendor/symfony/lock/Lock.php:116
Stack trace:
#0 /app/lock_test.php(11): Symfony\Component\Lock\Lock->acquire()
#1 {main}
  thrown in /app/vendor/symfony/lock/Lock.php on line 116

As you can see, SQLSTATE is effectively 42S02

And if you inspect the $errorInfo array of the PDOException it has the content

'errorInfo' => 
  array (
    0 => '42S02',
    1 => 1146,
    2 => 'Table \'testdb.lock_keys\' doesn\'t exist',
  )

This array contains the PDO::errorInfo() array which PHP manuals says that:

Element 0 is SQLSTATE error code (a five characters alphanumeric identifier defined in the ANSI SQL standard).
Element 1 is Driver-specific error code.
Element 2 is Driver-specific error message.

So, if we want to use the driver-specific error code (the 1146) we shouldn't check for the Exception code but the errorInfo array.

Thanks.
Ernesto

How to reproduce

I used Docker to test the component with this simple script:

<?php

require_once 'vendor/autoload.php';

$pdo = new PDO('mysql:host=mysql;dbname=testdb', 'testUser', 'testPass');
$store = new \Symfony\Component\Lock\Store\PdoStore($pdo);
$factory = new \Symfony\Component\Lock\LockFactory($store);

$lock = $factory->createLock('test-lock');

if ($lock->acquire()) {
    echo "Lock acquired\n";

    $lock->release();
} else {
    echo "Couldn't acquire lock\n";
}

PHP version 8.2.16
MySQL version 8.3.0
MariaDB version 11.3.2

Possible Solution

Either user the SQLSTATE error code for MySQL which is "42S02", or the second element of array erroInfo of the PDOException class which is 1146 as expected.

I consider that the most trivial solution is the first one 😄

Additional Context

No response

@edomato edomato added the Bug label Feb 27, 2024
edomato added a commit to edomato/symfony that referenced this issue Feb 27, 2024
* Closes bug: symfony#54091

Signed-off-by: Ernesto Domato <edomato@gmail.com>
edomato added a commit to edomato/symfony that referenced this issue Mar 8, 2024
* Closes bug: symfony#54091

Signed-off-by: Ernesto Domato <edomato@gmail.com>
nicolas-grekas pushed a commit to edomato/symfony that referenced this issue Mar 13, 2024
* Closes bug: symfony#54091

Signed-off-by: Ernesto Domato <edomato@gmail.com>
nicolas-grekas added a commit that referenced this issue Mar 13, 2024
…omato)

This PR was merged into the 5.4 branch.

Discussion
----------

[Lock] Check the correct SQLSTATE error code for MySQL

* Closes bug: #54091

| Q             | A
| ------------- | ---
| Branch?       | 5.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Issues        | Fix #54091
| License       | MIT

Commits
-------

7318816 [Lock] Check the correct SQLSTATE error code for MySQL
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants