Skip to content

Conversation

@terabytesoftw
Copy link
Member

@terabytesoftw terabytesoftw commented Aug 13, 2025

Q A
Is bugfix? ✔️
New feature?
Breaks BC?

Summary by CodeRabbit

  • Bug Fixes

    • Consistent response finalization in both success and error scenarios.
    • Request state now resets at the start of each new request, preventing data carry-over.
  • Refactor

    • Streamlined request handling to a single outcome path for more predictable behavior and easier maintenance.
  • Documentation

    • Updated behavior notes to reflect request-reset change in lifecycle descriptions.

@terabytesoftw terabytesoftw added the bug Something isn't working label Aug 13, 2025
@coderabbitai
Copy link

coderabbitai bot commented Aug 13, 2025

Walkthrough

handle() now captures terminate(...) result in a local variable and returns once; reset() now calls request->reset() after syncing the error handler response; terminate() no longer resets the request. No public signatures changed. (44 words)

Changes

Cohort / File(s) Summary
Stateless lifecycle and termination flow
src/http/StatelessApplication.php
handle(): unify exits by assigning terminate(...) result to $psrResponse and returning it once; reset(): call $this->request->reset() after updating error handler response; terminate(): remove request->reset() call. Docblocks updated to reflect relocation of request reset. No public API changes.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant StatelessApplication
    participant ErrorHandler
    participant Response

    Client->>StatelessApplication: handle(request)
    activate StatelessApplication
    alt success
        StatelessApplication->>StatelessApplication: process request
        StatelessApplication->>Response: build response
    else error
        StatelessApplication->>ErrorHandler: handle throwable
        ErrorHandler-->>StatelessApplication: error response
    end
    StatelessApplication->>StatelessApplication: terminate(response)
    StatelessApplication-->>Client: return response
    deactivate StatelessApplication

    Note over StatelessApplication: On next request reset():<br/>- errorHandler->setResponse(response)<br/>- request->reset()
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Possibly related PRs

Poem

I twitch my whiskers, tidy and spry,
One return now greets the sky.
Reset at dawn, terminate at night,
Errors handled, everything right.
A rabbit hops — lifecycle light. 🐇✨


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 96d6727 and 1630754.

📒 Files selected for processing (1)
  • src/http/StatelessApplication.php (4 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: terabytesoftw
PR: yii2-extensions/psr-bridge#53
File: src/http/ErrorHandler.php:258-272
Timestamp: 2025-08-03T16:24:09.241Z
Learning: In yii2-extensions/psr-bridge, the StatelessApplication creates a new Response instance for each request in the reset() method, then passes it to ErrorHandler::setResponse(). This means the template response is not shared across requests, so calling clear() on it in createErrorResponse() is safe and doesn't cause side effects.
Learnt from: terabytesoftw
PR: yii2-extensions/psr-bridge#53
File: src/http/ErrorHandler.php:258-272
Timestamp: 2025-08-03T16:24:09.241Z
Learning: In yii2-extensions/psr-bridge, the StatelessApplication creates a new Response instance for each request in the reset() method, then passes it to ErrorHandler::setResponse(). This means the template response is not shared across requests, so calling clear() on it in createErrorResponse() is safe and doesn't cause side effects.
Learnt from: terabytesoftw
PR: yii2-extensions/psr-bridge#53
File: src/http/ErrorHandler.php:258-272
Timestamp: 2025-08-03T16:24:09.241Z
Learning: In yii2-extensions/psr-bridge, the StatelessApplication creates a new Response instance for each request in the reset() method (line 408: `$this->response = new Response($this->components['response'] ?? []);`), then passes it to ErrorHandler::setResponse(). This means the template response is not shared across requests, so calling clear() on it in createErrorResponse() is safe and doesn't cause side effects.
📚 Learning: 2025-08-03T16:24:09.241Z
Learnt from: terabytesoftw
PR: yii2-extensions/psr-bridge#53
File: src/http/ErrorHandler.php:258-272
Timestamp: 2025-08-03T16:24:09.241Z
Learning: In yii2-extensions/psr-bridge, the StatelessApplication creates a new Response instance for each request in the reset() method, then passes it to ErrorHandler::setResponse(). This means the template response is not shared across requests, so calling clear() on it in createErrorResponse() is safe and doesn't cause side effects.

Applied to files:

  • src/http/StatelessApplication.php
📚 Learning: 2025-08-03T16:24:09.241Z
Learnt from: terabytesoftw
PR: yii2-extensions/psr-bridge#53
File: src/http/ErrorHandler.php:258-272
Timestamp: 2025-08-03T16:24:09.241Z
Learning: In yii2-extensions/psr-bridge, the StatelessApplication creates a new Response instance for each request in the reset() method (line 408: `$this->response = new Response($this->components['response'] ?? []);`), then passes it to ErrorHandler::setResponse(). This means the template response is not shared across requests, so calling clear() on it in createErrorResponse() is safe and doesn't cause side effects.

Applied to files:

  • src/http/StatelessApplication.php
🧬 Code Graph Analysis (1)
src/http/StatelessApplication.php (1)
src/http/Request.php (1)
  • reset (748-751)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: phpunit / PHP 8.3-windows-latest
  • GitHub Check: phpunit / PHP 8.1-ubuntu-latest
  • GitHub Check: phpunit / PHP 8.2-windows-latest
  • GitHub Check: phpunit / PHP 8.4-windows-latest
  • GitHub Check: mutation / PHP 8.3-ubuntu-latest
  • GitHub Check: mutation / PHP 8.3-ubuntu-latest
  • GitHub Check: phpunit / PHP 8.4-windows-latest
  • GitHub Check: phpunit / PHP 8.4-ubuntu-latest
🔇 Additional comments (5)
src/http/StatelessApplication.php (5)

278-284: Consolidated return path in handle() improves clarity

Assigning terminate(...) to $psrResponse in both paths and returning once is cleaner and equivalent behavior-wise.


374-382: Docblock now mentions request adapter reset — accurate and helpful

The lifecycle docs for reset() correctly reflect the added request adapter reset step.


410-413: Resetting Request adapter before injecting PSR-7 request is correct

This prevents adapter reuse across requests and aligns with the intended stateless behavior and our prior learning about per-request Response wiring to the ErrorHandler.


427-432: terminate() doc reflects actual responsibilities

Leaving request reset to reset() and documenting cleanup of events, uploaded files, and logs is accurate and keeps concerns well separated.


410-413: No additional request state to clear in Request::reset()

After inspecting src/http/Request.php, the reset() method only nulls the PSR-7 adapter—and that adapter is the sole holder of per-request data. All getters (getCookies(), getHeaders(), getParsedBody(), etc.) delegate to the adapter when it’s set, and there are no other cached properties on the Request object. Since each request calls reset() followed by setPsr7Request(), you always start with a fresh adapter and therefore no risk of cross-request state leakage. You can safely ignore this concern.

Likely an incorrect or invalid review comment.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix_mini_76

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

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

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@codecov
Copy link

codecov bot commented Aug 13, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (7d80a97) to head (1630754).
⚠️ Report is 1 commits behind head on main.
⚠️ Test Analytics upload error: File not in storage

Additional details and impacted files
@@             Coverage Diff             @@
##                main       #89   +/-   ##
===========================================
  Coverage     100.00%   100.00%           
  Complexity       319       319           
===========================================
  Files             12        12           
  Lines            801       802    +1     
===========================================
+ Hits             801       802    +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (4)
src/http/StatelessApplication.php (4)

278-284: Avoid type-hopping on $response (Response → ResponseInterface)

$response is a Yii Response until Line 278, then becomes a ResponseInterface. This implicit type change can confuse readers and static analyzers. Prefer distinct variables.

Example refactor keeping the single-exit pattern:

try {
    $this->reset($request);
    $this->state = self::STATE_BEFORE_REQUEST;
    $this->trigger(self::EVENT_BEFORE_REQUEST);
    $this->state = self::STATE_HANDLING_REQUEST;

    /** @phpstan-var Response $yiiResponse */
    $yiiResponse = $this->handleRequest($this->request);

    $this->state = self::STATE_AFTER_REQUEST;
    $this->trigger(self::EVENT_AFTER_REQUEST);
    $this->state = self::STATE_END;

    $psrResponse = $this->terminate($yiiResponse);
} catch (Throwable $e) {
    $psrResponse = $this->terminate($this->handleError($e));
}

return $psrResponse;

279-281: Verify catch-path assumptions: errorHandler availability before initialization failures

If reset() throws before parent::__construct finishes (e.g., bad config), $this->errorHandler may not be initialized. Then handleError($e) could throw and skip termination/cleanup.

Please verify that, in all environments, errorHandler is always available in this catch branch. If not guaranteed, consider a guarded fallback (minimal 500 Response) in case handleError() itself fails.


427-433: Docblock is outdated: terminate() no longer resets the request

The comment still claims terminate() “resets the request state,” but that responsibility moved to reset().

Apply this doc-only diff:

- * Cleans up registered events, resets uploaded files, flushes the logger, and resets the request state.
+ * Cleans up registered events, resets uploaded files, and flushes the logger.
+ * Note: Request state is reset in reset(), not here.

374-386: Clarify that reset() now resets the Request state

Consider explicitly mentioning the request reset in the method doc, since that responsibility moved here.

Suggested doc tweak:

- * Performs a full reinitialization of the application state, including event tracking, error handler cleanup,
- * session management, and PSR-7 request injection.
+ * Performs a full reinitialization of the application state, including event tracking, error handler cleanup,
+ * request adapter reset, session management, and PSR-7 request injection.
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7d80a97 and 96d6727.

📒 Files selected for processing (1)
  • src/http/StatelessApplication.php (2 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: terabytesoftw
PR: yii2-extensions/psr-bridge#53
File: src/http/ErrorHandler.php:258-272
Timestamp: 2025-08-03T16:24:09.241Z
Learning: In yii2-extensions/psr-bridge, the StatelessApplication creates a new Response instance for each request in the reset() method, then passes it to ErrorHandler::setResponse(). This means the template response is not shared across requests, so calling clear() on it in createErrorResponse() is safe and doesn't cause side effects.
Learnt from: terabytesoftw
PR: yii2-extensions/psr-bridge#53
File: src/http/ErrorHandler.php:258-272
Timestamp: 2025-08-03T16:24:09.241Z
Learning: In yii2-extensions/psr-bridge, the StatelessApplication creates a new Response instance for each request in the reset() method, then passes it to ErrorHandler::setResponse(). This means the template response is not shared across requests, so calling clear() on it in createErrorResponse() is safe and doesn't cause side effects.
Learnt from: terabytesoftw
PR: yii2-extensions/psr-bridge#53
File: src/http/ErrorHandler.php:258-272
Timestamp: 2025-08-03T16:24:09.241Z
Learning: In yii2-extensions/psr-bridge, the StatelessApplication creates a new Response instance for each request in the reset() method (line 408: `$this->response = new Response($this->components['response'] ?? []);`), then passes it to ErrorHandler::setResponse(). This means the template response is not shared across requests, so calling clear() on it in createErrorResponse() is safe and doesn't cause side effects.
📚 Learning: 2025-08-03T16:24:09.241Z
Learnt from: terabytesoftw
PR: yii2-extensions/psr-bridge#53
File: src/http/ErrorHandler.php:258-272
Timestamp: 2025-08-03T16:24:09.241Z
Learning: In yii2-extensions/psr-bridge, the StatelessApplication creates a new Response instance for each request in the reset() method, then passes it to ErrorHandler::setResponse(). This means the template response is not shared across requests, so calling clear() on it in createErrorResponse() is safe and doesn't cause side effects.

Applied to files:

  • src/http/StatelessApplication.php
📚 Learning: 2025-08-03T16:24:09.241Z
Learnt from: terabytesoftw
PR: yii2-extensions/psr-bridge#53
File: src/http/ErrorHandler.php:258-272
Timestamp: 2025-08-03T16:24:09.241Z
Learning: In yii2-extensions/psr-bridge, the StatelessApplication creates a new Response instance for each request in the reset() method (line 408: `$this->response = new Response($this->components['response'] ?? []);`), then passes it to ErrorHandler::setResponse(). This means the template response is not shared across requests, so calling clear() on it in createErrorResponse() is safe and doesn't cause side effects.

Applied to files:

  • src/http/StatelessApplication.php
🧬 Code Graph Analysis (1)
src/http/StatelessApplication.php (1)
src/http/Request.php (1)
  • reset (748-751)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: phpunit / PHP 8.2-windows-latest
  • GitHub Check: mutation / PHP 8.3-ubuntu-latest
  • GitHub Check: mutation / PHP 8.3-ubuntu-latest
🔇 Additional comments (2)
src/http/StatelessApplication.php (2)

278-284: Single exit and consistent termination — good change

Using a single return and ensuring terminate() runs in both success and error paths improves readability and guarantees cleanup. Looks good.


411-411: Resetting Request here is correct and aligns with stateless reuse

Calling $this->request->reset() before setPsr7Request() prevents stale adapters leaking across requests. This matches prior learnings about per-request state and is the right place to do it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants