Only catch UniqueConstraintViolationException in database session insert (fixes laravel/framework#57961)#7
Open
JoshSalway wants to merge 2 commits into12.xfrom
Open
Conversation
…ndler Verifies that DatabaseSessionHandler::performInsert() re-throws QueryException when the error is not a unique constraint violation. Refs laravel#57961 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
DatabaseSessionHandler::performInsert() caught all QueryException instances and silently fell back to an update. This suppressed real database errors (missing columns, schema mismatches) making them impossible to diagnose. Narrow the catch to UniqueConstraintViolationException, which is the only case where the insert-then-update fallback is appropriate (race condition on duplicate session ID). All other query errors are now properly propagated. Fixes laravel#57961 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes laravel#57961 -- The database session handler catches all
QueryExceptionerrors during insert, silently swallowing real database errors (missing tables, permission denied, connection failures) and falling through to an update that also fails, producing confusing error messages.Root Cause
The bug exists because
DatabaseSessionHandler::performInsert()catches the broadQueryExceptionclass when the insert fails, then falls through toperformUpdate(). The intent was to handle the specific case where a session ID already exists (race condition between two requests), butQueryExceptioncovers every possible database error -- missing tables, invalid columns, connection timeouts, permission denied, etc. These unrelated errors are silently caught and masked by a subsequent update failure.Why This Fix Works
This fix works because it narrows the catch clause to
UniqueConstraintViolationException, which is the specific subclass ofQueryExceptionthat represents a duplicate key violation. This is the only scenario where falling through toperformUpdate()makes sense -- the session record already exists, so updating it is the correct recovery. All other database errors now propagate immediately with their original, meaningful error messages.Alternatives Considered
We chose this approach over adding a SELECT-before-INSERT pattern because: (1) the race condition would still exist between the SELECT and INSERT; (2) the current insert-then-update pattern is a well-established "upsert" strategy that avoids extra queries; (3)
UniqueConstraintViolationExceptionwas specifically introduced in Laravel to enable this exact pattern -- precise catch handling for constraint violations. Catching the narrower exception preserves the upsert optimization while fixing the error-swallowing bug.Files Changed
src/Illuminate/Session/DatabaseSessionHandler.php-- Changed catch fromQueryExceptiontoUniqueConstraintViolationExceptiontests/Integration/Session/DatabaseSessionHandlerTest.php-- New test verifying non-unique-constraint errors are rethrown