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

PdoDriver: fix pdo connection in exception mode (target >=4.1.0) #293

Open
wants to merge 8 commits into
base: master
Choose a base branch
from

Conversation

jkuchar
Copy link
Contributor

@jkuchar jkuchar commented Jun 11, 2018

  • new feature
  • BC break? no (as original behaviour should be considered as broken)

see #292

@jkuchar jkuchar changed the title PdoDriver: fix pdo connection in exception mode PdoDriver: fix pdo connection in exception mode (target >=4.1.0) Jun 11, 2018
}

$this->affectedRows = null;
throw $this->createException($this->connection->errorInfo(), $sql, null);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not like this handling of error cases. Is is done twice, any ideas?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is your intention to make it work regardless of ATTR_ERRMODE, ie. with ERRMODE_WARNING and ERRMODE_EXCEPTION together?

Maybe you can use finally:

try {
    $res = $this->connection->query($sql);
    ...

} catch (\PDOException $e) {
} finally {
	throw $this->createException(isset($e) ?  $e->errorInfo : $this->connection->errorInfo(), $sql);
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Finally will be executed also on successful case, I have extracted this in main body of the function.


} catch (\PDOException $pdoException) {
$this->affectedRows = null;
throw $this->createException($pdoException->errorInfo, $sql, $pdoException);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not like that I need to pass $previous all around. Any ideas how to do better?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the PDOException does not contain any additional information, so there is no need to pass on the previous one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, as it is implementation detail, no code ever should depend on that. Gonna remove that

@dg dg force-pushed the master branch 4 times, most recently from 1ac208e to 9840c31 Compare June 22, 2018 09:47
@jkuchar
Copy link
Contributor Author

jkuchar commented Jul 6, 2018

There is one more problem to fix, there is also WARNING mode in which dibi probably should mute warnings and handle them by iteself consistently = throwing exception.

I would like to write few notes into comments into this function because it handles three things simulatanously and it is not obvious what is does for the first look.

@jkuchar
Copy link
Contributor Author

jkuchar commented Jul 6, 2018

One more thing - I will need to help a little with tests. What approach to go? Run all tests also in warning mode and exception mode? Or create just unit tests for this one function. I'm not shure what happend whan connection dies before ->rowCount() is called.

@dg
Copy link
Owner

dg commented Jul 8, 2018

Run all tests in warning mode and exception mode seems better to me.

I'm not shure what happend whan connection dies before ->rowCount() is called.

It's hard to test, I would probably let it go.

@jkuchar
Copy link
Contributor Author

jkuchar commented Jul 19, 2018

Run all tests in warning mode and exception mode seems better to me.

How to do that? Tester does not support running more @dataProviders. I will probably go for unit test specially for PdoDriver::query() and running that with more configurations.

@jkuchar
Copy link
Contributor Author

jkuchar commented Jul 23, 2018

Running all tests with different configuration can be made by passing evironemnt variables to tester runner and passing that to individual tests. These evironment variables can be then listened in boostrap.php and there it can be decided with way to setup PDO.

@jkuchar jkuchar mentioned this pull request Jul 26, 2018
@jkuchar
Copy link
Contributor Author

jkuchar commented Jul 31, 2018

@dg It is more complicated then it looked at first time. There are still unhandled getAttribute, startTransaction, ... calls which leaks exceptions. What about wrapping PDO connection into evelope which normalizes errors. Current approach would make PdoDriver quite complex. Alternative approach is to wrap pdo calls in "javascript way".

self::try(function() {return $this->connection->getAttribute();}, function () {success}, function() {failure});

However this leads into weakly typed code as PHP does not support generics.

@dg
Copy link
Owner

dg commented Aug 1, 2018

Another option is to have two drivers, one for exception mode and one for warnings mode. And forbid silent mode (it is nonsense mode).

And another one option: to switch PDO to warning mode and back before and after each operation.

@jkuchar
Copy link
Contributor Author

jkuchar commented Aug 2, 2018

As PDO can provide consistent API when configured, I will try to go for switching error modes. Hopefuly that will hot have any side effects. There should be none - as long as there will be no nesting or callbacks from inside of the driver.

BTW problem with silent mode is that it is default. Current implementation of PdoDriver relays on silent mode.

API that changes by configuration is hell🔥.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants