Repository navigation
Require PDO exception mode and classify database failures by their causes - #678
Conversation
Reject warning and silent error modes at the shared physical connection boundary, including reconnects and effective read/write options. Failed statements must throw rather than allow a transaction to continue after a false result. Other PDO options and public statement return types remain unchanged. Remove the obsolete false-result fallback for internal session statements while preserving invalidation and propagation of the original failure. Update schema restoration fixtures to throw native PDO failures and retain cleanup, committed-schema and exception-identity assertions. Add rejection coverage through the real SQLite connector.
Unwrap query exceptions before classification and reject arbitrary application or transport exception text. This prevents filesystem warnings and HTTP failures from reconnecting database sessions or stopping queue workers merely because their messages resemble database errors. Preserve PDO message fallbacks, the existing lost-session signal and native mysqlnd protocol warnings that can still occur in exception mode. Keep custom detector bindings authoritative and retain the worker filter that excludes unrelated job failures even when a bound detector would accept their messages.
Require an underlying PDO failure in the default concurrency detector while retaining SQLSTATE, native driver codes and message fallbacks. HTTP response bodies and custom exception codes no longer cause transaction callbacks to be replayed accidentally; custom drivers keep the existing policy extension points. Treat DeadlockException as a retryable signal at the outer transaction boundary. Nested custom-driver failures have already been classified before the framework wraps them, and matching that wrapper again can lose the original decision. Retries still require successful cleanup, transaction level zero and remaining attempts. Explicit application-thrown DeadlockException instances follow the same rule. Cover the nested custom-driver regression, retain cancellation and cleanup assertions, and update simulated PDO failures without weakening their retry premises. Verify that an HTTP failure containing database lock text executes its transaction callback only once.
Unwrap nested query exceptions and require a PDO cause before applying MySQL invalid-value codes and message matching. An external-service response or SQL binding containing MySQL error text must remain an ordinary QueryException rather than become an InvalidValueException. MariaDB inherits the same correction. Cover genuine nested invalid values alongside HTTP-body and query-context false positives, preserving the original exception chain. Add a statement-listener warning regression that proves the existing PDO is retained and the reconnect callback is never invoked.
Explain the connection-time requirement, supplied PDO and custom connector responsibilities, and the existing detector bindings for non-PDO drivers. Preserve Laravel-style query exception wrapping and show how custom policies inspect the underlying cause without matching SQL or bindings. Record the deliberate configuration and default-recovery differences in the package README and porting guide. Remove the fulfilled warning-mode follow-up and retain the implementation plan with its rationale, removal audit and verification scope. Formatting, static analysis, targeted tests, Testbench, dogfood and all four database integration runners passed. Full parallel reruns stalled near completion and remain incomplete; no timing workaround or test exclusion was added.
|
@coderabbitai review |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Merge Risk: ⚪ Minimal · up to
|
PR Summary by QodoRequire PDO exception mode and classify database failures by cause
AI Description
Diagram
High-Level Assessment
Files changed (21)
|
✅ Action performedReview finished.
|
Code Review by Qodo🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)
Great, no issues found!Qodo reviewed your code and found no material issues that require reviewTip of the day💡 Did you know, you can import rules and skills only from the repositories your team follows |
PDO connections already default to exception mode, but applications can override that setting. In silent mode, or warning mode with warnings suppressed, a failed statement can return
falseand let a transaction commit incomplete work. This PR requires exception mode when the framework creates a PDO connection.Exception mode has been PDO's default since PHP 8.0. Modern framework database layers already build around it: Symfony's standard Doctrine integration uses DBAL, which explicitly sets exception mode, while Tempest's PDO connection relies on PHP's default and exposes no error-mode option in its connection setup. Requiring the same contract in Hypervel removes legacy support for warning and silent modes, simplifies failure handling, and eliminates fallback logic for statements that fail without throwing.
It also fixes recovery decisions that match database error text in unrelated exceptions. A filesystem warning from a statement listener can cause a reconnect, an HTTP response containing “database is locked” can repeat a transaction callback, and a wrapped transport failure can stop a queue worker. Recovery should follow the underlying database failure, while preserving Laravel-style query exceptions for application error handling.
Connection requirements
Failure classification and retries
DeadlockException, the outer transaction accepts that signal without requiring the custom policy to recognize the framework wrapper. An application-thrownDeadlockExceptionfollows the same rule. Retries still require successful cleanup, no remaining transaction levels and an available attempt.InvalidValueException.QueryExceptionwrapping, original causes, public method signatures and cancellation propagation remain intact. The mode check runs once per physical connection attempt; the other changes run on failure paths. Successful queries gain no extra checks, round trips or retained state.Documentation and tests
The database guide documents the mode requirement and shows how a custom driver extends the default detectors. The porting guide and package README describe the configuration and recovery differences, and the completed warning-mode TODO is removed.
Regression coverage includes rejected modes, unrelated HTTP and filesystem failures, nested exception classification, custom-driver transaction retries and worker detector filtering. Schema restoration fixtures now throw native PDO failures while preserving their cleanup, ordering and exception-identity assertions.
Validation
Note
Require PDO exception mode and classify database failures by their cause
Connector.createConnectionnow throwsInvalidArgumentExceptionwhen the configured PDO error mode is warning or silent; an unset mode defaults toPDO::ERRMODE_EXCEPTION(Connector.php)ConcurrencyErrorDetector,LostConnectionDetector, andMySqlConnection.isDataTypeErrornow unwrapQueryExceptionand classify onlyPDOException(orLostConnectionException) causes. Generic exceptions or HTTP failures with database-like text are no longer treated as database failuresLostConnectionDetectoradds explicit mysqlnd packet-warning prefixes as recognized lost-connection signalsManagesTransactions.handleTransactionExceptionretries cleaned-upDeadlockExceptionfailures even when the detector does not recognize the wrapper;PdoConnection.executeSessionStatementno longer throws whenPDO::execreturns falseMacroscope summarized 58f739f.
Summary by CodeRabbit
falseresult into a synthetic exception.