Skip to content

fix: send createSession 201 only after the transaction commits - #1461

Open
ionfwsrijan wants to merge 1 commit into
Canopus-Labs:mainfrom
ionfwsrijan:fix/1442-create-session-transaction
Open

fix: send createSession 201 only after the transaction commits#1461
ionfwsrijan wants to merge 1 commit into
Canopus-Labs:mainfrom
ionfwsrijan:fix/1442-create-session-transaction

Conversation

@ionfwsrijan

Copy link
Copy Markdown
Contributor

Problem

createSession (backend/controllers/sessionController.js) runs all writes inside mongoSession.withTransaction(async () => { ... }), but:

  • Lines 95–98: res.status(201).json(...) is sent inside the callback — before Mongoose commits. If the commit subsequently fails (network error, replica-set failover, duplicate key on a concurrent write), the client already got a 201 + full session object while the transaction was rolled back: a phantom success.
  • Lines 39–57: validation failures return res.status(400) inside the callback. Mongoose's withTransaction commits based on the callback's return value, so returning an Express response object commits instead of aborting — the opposite of the code's obvious intent.

Fix

  • Validate before opening the transactionrole/experience/MAX_SESSIONS checks now run first and return 4xx from the outer handler, never from inside the callback.
  • Move res.* out of the callback — the callback returns the created session, and res.status(201).json(...) is sent only after withTransaction resolves (i.e. after commit).
  • The SESSION_LIMIT_REACHED throw is replaced by an early 400 return ahead of the transaction.
  • endSession() stays in finally, guarded for the pre-transaction validation paths.

Files changed

  • backend/controllers/sessionController.js — restructured createSession.
  • backend/tests/sessionController.create.transaction.unit.test.js — tests for 400s without starting a transaction, no 201 on commit failure, and 201 only after commit.

Testing

npx vitest run tests/sessionController.create.transaction.unit.test.js — 5/5 passing.

Closes #1442

The success response and 4xx validation returns were issued inside the
withTransaction callback, so a 201 could reach the client before the commit
finished (phantom success on rollback), and returning res inside the callback
resolved it as a commit instead of an abort. Move validation ahead of the
transaction, return the created session from the callback, and send the
response only after withTransaction resolves.

Closes Canopus-Labs#1442
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@ionfwsrijan, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 50 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 1bb0cfb9-09b2-436a-9f9e-7af66d21237c

📥 Commits

Reviewing files that changed from the base of the PR and between 8acb5b8 and 830c85c.

📒 Files selected for processing (2)
  • backend/controllers/sessionController.js
  • backend/tests/sessionController.create.transaction.unit.test.js

Comment @coderabbitai help to get the list of available commands.

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.

createSession sends the HTTP 201 response inside the withTransaction callback — before the transaction commits

1 participant