Skip to content

Conversation

@terabytesoftw
Copy link
Member

@terabytesoftw terabytesoftw commented Aug 19, 2025

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

Summary by CodeRabbit

  • New Features

    • Added a configurable option to control whether logs are flushed automatically when the application terminates.
  • Tests

    • Added tests ensuring exceptions return consistent 500 responses.
    • Added a test verifying exception-related internal state is reset between requests.
    • Added a test confirming exceptions are recorded by the logger when logging is configured.

@coderabbitai
Copy link

coderabbitai bot commented Aug 19, 2025

Walkthrough

Adds tests for ErrorHandler and StatelessApplication and a configurable logger-flush property on StatelessApplication; tests verify ErrorHandler leaves its internal exception property null and that exceptions are logged when a FileTarget is configured. StatelessApplication.terminate() now conditionally flushes the instance logger based on a new public property.

Changes

Cohort / File(s) Summary
Error handler tests
tests/http/ErrorHandlerTest.php
Added testHandleExceptionSetsExceptionPropertyAndResetsIt: reads private/internal exception property via inaccessibleProperty before/after handleException, asserts it's null both times, and verifies the returned response status is 500.
Stateless application tests
tests/http/StatelessApplicationTest.php
Added testLogExceptionIsCalledWhenHandlingException: configures a FileTarget log target, triggers an exception during request handling, asserts response is 500 and that the instance logger contains an entry originating from an exception with the expected message.
Application runtime
src/http/StatelessApplication.php
Added public bool $flushLogger = true property; terminate() now conditionally flushes the application instance logger using $this->getLog()->getLogger()->flush(true) only when $flushLogger is true, and removed the unused use Yii;.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Client
  participant App as StatelessApplication
  participant Handler as ErrorHandler
  participant Logger as AppLogger

  Client->>App: send request
  App->>App: handleRequest()
  alt exception thrown
    App->>Handler: handleException(e)
    Handler-->>App: Response(500)
    note right of Handler #E8F5E9: test reads internal exception\nproperty before/after and asserts null
    App->>Logger: log(error, e)
  end
  alt flushLogger == true
    App->>Logger: flush(true)
    note right of Logger #FFF3E0: instance logger flush called\n($this->getLog()->getLogger()->flush(true))
  else flushLogger == false
    note right of App #FFEBEE: no logger flush performed
  end
  App-->>Client: send Response
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

bug

Poem

I hop through code with eager paws,
I sniff the logs and read the laws.
Exceptions checked and logger tuned,
A tidy flush — no panic loomed.
I thump my foot — the tests all pass! 🐇✨

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.


📜 Recent review details

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

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 9a559b3 and 303b6ba.

📒 Files selected for processing (1)
  • tests/http/StatelessApplicationTest.php (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/http/StatelessApplicationTest.php
⏰ 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.1-windows-latest
  • GitHub Check: mutation / PHP 8.3-ubuntu-latest
  • GitHub Check: mutation / PHP 8.3-ubuntu-latest
✨ 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_89

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 19, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (35cfe93) to head (303b6ba).

Additional details and impacted files
@@             Coverage Diff             @@
##                main      #103   +/-   ##
===========================================
  Coverage     100.00%   100.00%           
- Complexity       319       320    +1     
===========================================
  Files             12        12           
  Lines            809       810    +1     
===========================================
+ Hits             809       810    +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 (1)
tests/http/ErrorHandlerTest.php (1)

156-184: Align test name with assertions or assert interim “set” state.

The method name suggests verifying both that the exception property is set during handling and reset after. Currently it only checks null before and null after. Either:

  • Rename to better reflect behavior, or
  • Assert that the property is set during rendering via a small test double.

Example (preferred): capture the property during render to assert it was set, then still verify it resets:

-    public function testHandleExceptionSetsExceptionPropertyAndResetsIt(): void
+    public function testHandleExceptionSetsExceptionPropertyAndResetsIt(): void
     {
-        $errorHandler = new ErrorHandler();
-
-        $errorHandler->discardExistingOutput = false;
+        $errorHandler = new class () extends ErrorHandler {
+            public ?Throwable $capturedException = null;
+            protected function renderException($exception): Response
+            {
+                // Assert property is set during handling.
+                $this->capturedException = $this->exception;
+                return parent::renderException($exception);
+            }
+        };
+        $errorHandler->discardExistingOutput = false;
 
         $initialException = self::inaccessibleProperty($errorHandler, 'exception');
 
         self::assertNull(
             $initialException,
             "Exception property should be 'null' initially.",
         );
 
         $exception = new Exception('Test exception for property verification');
 
         $response = $errorHandler->handleException($exception);
 
+        self::assertSame(
+            $exception,
+            $errorHandler->capturedException,
+            'Exception property should be set while handling exception.',
+        );
+
         $finalException = self::inaccessibleProperty($errorHandler, 'exception');
 
         self::assertNull(
             $finalException,
             "Exception property should be reset to 'null' after handling exception.",
         );
         self::assertSame(
             500,
             $response->getStatusCode(),
             'Should set correct status code and reset exception property.',
         );
     }

If you prefer not to use a test double, consider renaming to testHandleExceptionResetsExceptionProperty() to match the current assertions.

📜 Review details

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

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 35cfe93 and 63a19fa.

📒 Files selected for processing (1)
  • tests/http/ErrorHandlerTest.php (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
tests/http/ErrorHandlerTest.php (1)
src/http/ErrorHandler.php (2)
  • ErrorHandler (39-263)
  • handleException (113-134)
⏰ 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 (1)
tests/http/ErrorHandlerTest.php (1)

156-184: Good addition: verifies exception state is null before/after and status code 500.

This test strengthens the contract around ErrorHandler::handleException resetting its internal state and returning a 500 for generic exceptions. Looks correct and consistent with the implementation.

…corresponding test for exception logging.
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 (2)
src/http/StatelessApplication.php (1)

463-465: Conditional flush via instance logger is correct; minor optimization possible.

Using the instance logger path ($this->getLog()->getLogger()) instead of the global is the right move here. If you want to shave a tiny bit of overhead, you could skip flushing when there are no buffered messages:

-        if ($this->flushLogger) {
-            $this->getLog()->getLogger()->flush(true);
-        }
+        if ($this->flushLogger) {
+            $logger = $this->getLog()->getLogger();
+            if (!empty($logger->messages)) {
+                $logger->flush(true);
+            }
+        }

Also consider updating the method doc above to say it “conditionally flushes the logger” to reflect the new behavior.

tests/http/StatelessApplicationTest.php (1)

583-652: Solid test of exception logging; tighten a couple of details for robustness.

  • Prefer using the class constant for the expected category to avoid string drift.
  • Make the test’s intent explicit by asserting the app is configured not to flush.

Proposed changes:

-        $expectedCategory = 'yii\base\Exception';
+        $expectedCategory = Exception::class;
         $app = $this->statelessApplication(
             [
                 'flushLogger' => false,
                 'components' => [
                     'errorHandler' => [
                         'errorAction' => null,
                     ],
                     'log' => [
                         'traceLevel' => YII_DEBUG ? 1 : 0,
                         'targets' => [
                             [
                                 'class' => FileTarget::class,
                                 'levels' => [
                                     'error',
                                 ],
                             ],
                         ],
                     ],
                 ],
             ],
         );
+
+        self::assertFalse(
+            $app->flushLogger,
+            "Test must keep logger messages in memory to assert on them; 'flushLogger' should be false."
+        );
📜 Review details

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

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 63a19fa and 9a559b3.

📒 Files selected for processing (2)
  • src/http/StatelessApplication.php (2 hunks)
  • tests/http/StatelessApplicationTest.php (2 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 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
🧬 Code Graph Analysis (2)
src/http/StatelessApplication.php (1)
tests/support/stub/MockerFunctions.php (1)
  • flush (93-96)
tests/http/StatelessApplicationTest.php (3)
tests/support/FactoryHelper.php (2)
  • FactoryHelper (46-268)
  • createServerRequestCreator (154-161)
tests/TestCase.php (1)
  • statelessApplication (124-187)
src/http/StatelessApplication.php (1)
  • handle (269-295)
⏰ 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.1-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 (1)

51-65: Configurable logger flush flag is a good addition (sensible default and clear docs).

Public bool with default true fits the worker use-case and stays BC. The docblock sets expectations and warns appropriately. This integrates cleanly with your delayed parent::__construct($config) call in reset(), so 'flushLogger' => false in app config is honored at runtime.

tests/http/StatelessApplicationTest.php (1)

16-16: Importing FileTarget is necessary for the new logging test.

This aligns the test with the configured log target.

@terabytesoftw terabytesoftw deleted the fix_mini_89 branch August 19, 2025 18:36
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.

2 participants