Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle missing dependencies in setter methods with @Inject(optional=true) #292

Merged
merged 3 commits into from
Nov 28, 2024

Conversation

koriym
Copy link
Member

@koriym koriym commented Nov 28, 2024

Add try-catch block to manage missing dependencies during method injection. When a method is annotated with @Inject(optional=true), the code now returns gracefully if no dependency is provided. For methods with @Inject(optional=false), an exception is thrown if the dependency is unbound.

Summary by CodeRabbit

  • New Features

    • Improved error handling for optional dependency injection in the setter method.
    • Enhanced logic to manage Unbound exceptions based on the isOptional property.
    • Updated type safety for various classes, ensuring parameters and properties are more explicitly defined.
    • Introduced a new exception class for handling non-writable directories.
  • Bug Fixes

    • Resolved issues related to required dependencies not being properly managed.

Add try-catch block to manage missing dependencies during method injection. When a method is annotated with @Inject(optional=true), the code now returns gracefully if no dependency is provided. For methods with @Inject(optional=false), an exception is thrown if the dependency is unbound.
Copy link

coderabbitai bot commented Nov 28, 2024

Walkthrough

The SetterMethod class in src/di/SetterMethod.php has been modified to enhance error handling in the accept method. A try-catch block has been introduced to manage Unbound exceptions. If an exception is caught, the method checks the isOptional property; if true, it exits without error, allowing optional dependency injection. If false, the exception is re-thrown, indicating a required dependency is missing. The changes also include updates to method signatures and return types in various classes to improve type safety and clarity.

Changes

File Change Summary
src/di/SetterMethod.php Modified accept method to include try-catch for Unbound exception; checks isOptional property.
src/di/AspectBind.php Changed return type of inject method from array<string, array<MethodInterceptor>> to array<string, list<MethodInterceptor>>.
src/di/AssistedInjectInterceptor.php Updated getNamedArguments method to specify MethodInvocation<object> type hint.
src/di/ContainerFactory.php Updated __invoke method to require a new parameter string $classDir.
src/di/Dependency.php Removed PHPStan ignore comment from weaveAspects method call.
src/di/Grapher.php Changed type annotation for $classDir property and constructor parameter to non-empty-string.
src/di/Injector.php Updated $classDir property type to non-empty-string and clarified $module parameter type in constructor.
src/di/MethodInvocationProvider.php Updated property and method signatures to use MethodInvocation<object> for type safety.
src/di/MultiBinding/LazyTo.php Removed PHPStan ignore comment from __invoke method.
src/di/SpyCompiler.php Added PHPStan ignore comment to suppress warnings in compile method.
src/di/Exception/DirectoryNotWritable.php Introduced new exception class DirectoryNotWritable extending RuntimeException.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant SetterMethod
    participant Visitor

    Client->>SetterMethod: call accept(visitor)
    SetterMethod->>Visitor: visitSetterMethod()
    alt Unbound Exception
        Visitor-->>SetterMethod: throws Unbound
        SetterMethod->>SetterMethod: check isOptional
        alt isOptional is true
            SetterMethod-->>Client: return (no error)
        else isOptional is false
            SetterMethod-->>Client: throw Unbound
        end
    else No Exception
        SetterMethod-->>Client: proceed normally
    end
Loading

🐇 "In the land of code, where errors once roamed,
A catch was embraced, and the bugs were disowned.
Optional paths now lead to delight,
With dependencies handled, everything's right!
So hop along, friends, with joy let us sing,
For our SetterMethod shines bright like a spring!" 🌼

Possibly related PRs

  • Implements visitor pattern #289: Implements visitor pattern - This PR adds the accept method to the SetterMethod class, which is directly related to the changes made in the main PR that also modifies the accept method in the same class.
  • Serializable provider provider #291: Enhances visitor pattern - The Dependency class in the main PR implements the AcceptInterface, reflecting changes made in the retrieved PR where the Dependency class also implements AcceptInterface.

Suggested reviewers

  • NaokiTsuchiya
  • jingu

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ 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.
    • Generate unit testing code for this file.
    • 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. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • 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 src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

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

Documentation and Community

  • 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.

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

🧹 Outside diff range and nitpick comments (1)
src/di/SetterMethod.php (1)

70-80: Consider refactoring duplicate error handling logic.

The error handling pattern is duplicated between accept() and __invoke() methods. Consider extracting this into a private method to maintain DRY principles.

Here's a suggested refactoring:

+ private function handleUnboundException(Unbound $e): void 
+ {
+     if ($this->isOptional) {
+         return;
+     }
+     
+     throw $e;
+ }

  public function __invoke($instance, Container $container): void
  {
      try {
          $parameters = $this->arguments->inject($container);
      } catch (Unbound $e) {
-         if ($this->isOptional) {
-             return;
-         }
-
-         throw $e;
+         $this->handleUnboundException($e);
+         return;
      }
      // ... rest of the method
  }

  public function accept(VisitorInterface $visitor)
  {
      try {
          $visitor->visitSetterMethod($this->method, $this->arguments);
      } catch (Unbound $e) {
-         if ($this->isOptional) {
-             return;
-         }
-
-         throw $e;
+         $this->handleUnboundException($e);
+         return;
      }
  }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 3155fc6 and 6e56567.

📒 Files selected for processing (1)
  • src/di/SetterMethod.php (1 hunks)
🔇 Additional comments (2)
src/di/SetterMethod.php (2)

70-80: LGTM! The error handling implementation aligns with the PR objectives.

The try-catch block correctly implements the intended behavior:

  • Returns silently for @Inject(optional=true) when dependency is missing
  • Throws exception for @Inject(optional=false) when dependency is missing

The code comments clearly document the behavior in both scenarios.


70-80: Verify error handling consistency across the codebase.

Let's ensure this error handling pattern is consistently applied across other dependency injection scenarios in the codebase.

✅ Verification successful

Based on the results, I can now generate the final response:

Error handling for Unbound exceptions is consistently implemented across the codebase

The verification shows that error handling for Unbound exceptions follows consistent patterns throughout the codebase:

  • In SetterMethod.php: Optional dependencies are handled by checking isOptional
  • In Arguments.php: Similar pattern using isDefaultAvailable() for default values
  • Demo files only contain example error handling for demonstration purposes

The implementation in the reviewed code aligns with the codebase's established patterns for handling unbound dependencies.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other Unbound exception handling patterns
rg -A 5 "catch \(.*Unbound" --type php

# Search for other optional injection patterns
ast-grep --pattern 'if ($this->isOptional) {
  $$$
}'

Length of output: 2092

Removed unnecessary type suppression comments and refined type annotations to enhance code clarity across multiple classes. Updated several development dependencies in the composer.lock to their latest versions, ensuring compatibility and consistency. This update primarily affects internal documentation and tooling without altering functionality.
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: 1

🧹 Outside diff range and nitpick comments (5)
src/di/AspectBind.php (1)

Based on the results from our searches, I can now provide the final response:

Add type structure tests for AspectBind::inject method

The codebase lacks specific test coverage for verifying the return type structure of AspectBind::inject. While there are several interceptor implementations and basic visitor tests, none explicitly verify that:

  • The returned array has string keys (method names)
  • The values are lists of MethodInterceptor instances
  • The overall structure matches array<string, list<MethodInterceptor>>

Suggested test locations:

  • Add test cases in tests/di/VisitorTest.php or create a new AspectBindTest.php
🔗 Analysis chain

Line range hint 25-41: Consider adding type structure verification tests.

While the implementation correctly produces a list structure, it would be valuable to add tests that verify the return type structure matches the new stricter type declaration.

Let's check for existing tests that verify the return structure:


Let me gather more information about the test coverage for AspectBind.


Let me check for specific test cases that verify the AspectBind's inject method and its return type structure.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Look for test cases that verify the structure of AspectBind::inject return value

# Search for test files related to AspectBind
fd -e php AspectBind --exec rg -l "class.*Test.*AspectBind"

# Search for specific test assertions about the return structure
rg -A 3 "inject.*Container" "tests/"

Length of output: 342


Script:

#!/bin/bash
# Search for test files containing AspectBind tests with broader context
rg -l "AspectBind" tests/

# Look for test assertions related to method interception or bindings
rg -A 5 "MethodInterceptor|getBindings|AspectBind" tests/

# Check if there are any test files that might have been renamed
fd -e php test --exec rg -l "AspectBind"

Length of output: 9192


Script:

#!/bin/bash
# Search for test cases specifically related to AspectBind's inject method
rg -B 5 -A 10 "AspectBind.*inject" tests/

# Look for test assertions that verify array structure or types
rg -B 2 -A 5 "assertInstanceOf.*MethodInterceptor|assert.*array.*MethodInterceptor" tests/

# Check if there are any test files in a different directory
fd -t f -e php -e phpt . --exec rg -l "AspectBind.*test"

Length of output: 195

src/di/ContainerFactory.php (1)

Line range hint 17-26: Consider adding runtime validation for non-empty string.

While the docblock specifies non-empty-string, it would be safer to add runtime validation for the $classDir parameter.

 public function __invoke($module, string $classDir): Container
 {
+    if ($classDir === '') {
+        throw new InvalidArgumentException('Class directory path cannot be empty');
+    }
     $oneModule = $this->getModule($module);
     // install built-in module
     $appModule = (new BuiltinModule())($oneModule);
src/di/Grapher.php (1)

Line range hint 29-35: Add runtime validation for non-empty class directory.

While the @param non-empty-string annotation provides static analysis safety, the runtime type hint is still string. Consider adding a runtime check to ensure the contract is maintained.

 public function __construct(AbstractModule $module, string $classDir)
 {
+    if ($classDir === '') {
+        throw new \InvalidArgumentException('Class directory path cannot be empty');
+    }
     $module->install(new AssistedModule());
     $this->container = $module->getContainer();
     $this->classDir = $classDir;
src/di/Injector.php (1)

Line range hint 67-67: Consider adding runtime class validation

While the @psalm-var class-string annotation helps with static analysis, consider adding runtime validation to ensure $interface is a valid class name.

Consider adding validation:

 /** @psalm-var class-string $interface */
+if (!class_exists($interface) && !interface_exists($interface)) {
+    throw new \InvalidArgumentException(sprintf('"%s" is not a valid class or interface name', $interface));
+}
 $this->bind($interface);
src/di/AssistedInjectInterceptor.php (1)

66-67: Consider adding type parameter to invoke method for consistency.

For consistency, consider adding the same type parameter to the public invoke method signature:

-    public function invoke(MethodInvocation $invocation)
+    public function invoke(MethodInvocation<object> $invocation)
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 6e56567 and 158425d.

⛔ Files ignored due to path filters (1)
  • vendor-bin/tools/composer.lock is excluded by !**/*.lock
📒 Files selected for processing (9)
  • src/di/AspectBind.php (1 hunks)
  • src/di/AssistedInjectInterceptor.php (1 hunks)
  • src/di/ContainerFactory.php (1 hunks)
  • src/di/Dependency.php (1 hunks)
  • src/di/Grapher.php (1 hunks)
  • src/di/Injector.php (2 hunks)
  • src/di/MethodInvocationProvider.php (1 hunks)
  • src/di/MultiBinding/LazyTo.php (1 hunks)
  • src/di/SpyCompiler.php (1 hunks)
✅ Files skipped from review due to trivial changes (3)
  • src/di/Dependency.php
  • src/di/MultiBinding/LazyTo.php
  • src/di/SpyCompiler.php
🔇 Additional comments (11)
src/di/MethodInvocationProvider.php (4)

15-15: LGTM! Type safety improvement

The addition of the generic type parameter <object> enhances type safety by explicitly declaring that this MethodInvocation works with object types.


18-20: LGTM! Consistent type documentation

The parameter type documentation aligns with the property type, maintaining type consistency throughout the class.


Line range hint 1-36: Consider similar type improvements in related classes

The type safety improvements in this class are excellent. Consider applying similar generic type parameters to other classes that work with MethodInvocation to maintain consistency across the codebase.

Let's check for other classes that might benefit from similar improvements:


26-28: LGTM! Type-safe return value with proper error handling

The return type documentation ensures type consistency with the property, and the implementation properly handles the null case with an appropriate exception.

Let's verify the exception handling is consistent across the codebase:

✅ Verification successful

Exception handling is properly implemented and tested

The verification shows that:

  • The exception is properly defined as a subclass of Unbound
  • It's used consistently in MethodInvocationProvider
  • Test coverage exists in both PHP 8 (tests-php8/AssistedInjectTest.php) and earlier versions (tests/di/AssistedTest.php)
  • Tests explicitly verify the exception is thrown when method invocation is not available
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for consistent usage of MethodInvocationNotAvailable exception
# and verify it's properly caught where needed

# Check for other places where this exception is thrown
rg "throw new MethodInvocationNotAvailable" -A 2

# Check for exception handling
rg "catch.*MethodInvocationNotAvailable" -A 2

Length of output: 271


Script:

#!/bin/bash
# Let's verify if the exception class exists and check its usage pattern
# First, find the exception class
fd "MethodInvocationNotAvailable.php"

# Then check where this exception is used (imported/referenced)
rg "use.*MethodInvocationNotAvailable" 

# Also check for any try-catch blocks in files that might handle this type of exception
rg "try\s*{" -A 10 src/di/

Length of output: 484


Script:

#!/bin/bash
# Let's check the test files to understand how this exception is handled
rg -A 5 "MethodInvocationNotAvailable" tests-php8/AssistedInjectTest.php tests/di/AssistedTest.php

# Also check the exception class implementation
cat src/di/Exception/MethodInvocationNotAvailable.php

# Check for try blocks with fixed regex
rg "try {" -A 5 src/di/

Length of output: 1603

src/di/AspectBind.php (1)

25-25: LGTM! Type refinement accurately reflects the data structure.

The change from array<MethodInterceptor> to list<MethodInterceptor> better represents the sequential nature of the interceptors array, making the contract more precise. This aligns well with the implementation which uses array append operations.

src/di/ContainerFactory.php (2)

14-15: LGTM! Well-documented parameter constraints.

The docblock clearly specifies the type constraints for both parameters, particularly the non-empty-string requirement for $classDir which aligns with the type safety improvements across the codebase.


17-17: Verify all callers are updated with the new required parameter.

The method signature change requires all callers to provide a $classDir parameter. Let's verify this change doesn't break existing code.

✅ Verification successful

All callers have been updated with the new required parameter

The verification shows that all callers of ContainerFactory::__invoke() are already updated with the new $classDir parameter:

  • tests/di/VisitorTest.php: (new ContainerFactory())(new FakeCarModule(), __DIR__ . '/tmp')
  • src/di/Injector.php: (new ContainerFactory())($module, $this->classDir)
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find all calls to ContainerFactory::__invoke to ensure they're updated
# with the new required parameter

# Search for ContainerFactory instantiation and usage
rg -l "ContainerFactory" | while read -r file; do
  if [[ "$file" != "src/di/ContainerFactory.php" ]]; then
    echo "=== $file ==="
    rg -A 2 "ContainerFactory" "$file"
  fi
done

# Search for potential test files that might need updates
fd -e php -e phpt | rg -l "ContainerFactory"

Length of output: 1063

src/di/Grapher.php (2)

24-25: LGTM! Documentation matches the type constraint.

The PHPDoc annotation correctly reflects the non-empty-string type requirement for the $classDir parameter.


17-17: LGTM! Verify usage of non-empty-string type.

The stricter type annotation improves type safety by ensuring the class directory path is never empty. This is crucial as the property is used for class autoloading.

Let's verify this type is consistently used across the codebase:

✅ Verification successful

Let me gather more context about the usage of $classDir to ensure type consistency:


Let me try a different approach to check the usage:


Let me check one more thing to verify the property visibility and usage:


Type annotation change is consistent across the codebase

Based on the search results, the non-empty-string type annotation is consistently used across all related files (Grapher.php, Injector.php, and ContainerFactory.php) where $classDir is used. The constructor properly assigns the value, and the type constraint ensures the directory path can never be empty, which is crucial for class autoloading functionality.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for consistent usage of non-empty-string type for classDir
# Look for similar class directory parameters in other files

# Search for class directory related parameters
rg -t php "(?i)(classdir|class_dir|directory)\s*[:=].*string"

# Search for non-empty-string usage
rg -t php "non-empty-string"

Length of output: 444


Script:

#!/bin/bash
# Search for $classDir usage in these files
ast-grep --pattern '$classDir'

# Also check constructor parameters and property declarations
ast-grep --pattern 'function __construct($$$classDir$$$)'

Length of output: 92


Script:

#!/bin/bash
# Search for classDir parameter in constructors and its usage
rg -t php "function\s+__construct.*classDir" -A 5

# Check property declarations
rg -t php "protected\s+\$classDir|private\s+\$classDir|public\s+\$classDir" -A 2

Length of output: 533


Script:

#!/bin/bash
# Search for all $classDir property declarations with any visibility
rg -t php "\s+\$classDir\s*;" -B 2

# Search for where $classDir is used
rg -t php "\$classDir" -B 1 -A 1

Length of output: 69

src/di/Injector.php (1)

21-21: LGTM: Improved type safety with non-empty-string

The change from string to non-empty-string enhances type safety by ensuring the class directory path can never be empty, which is crucial for proper class loading.

src/di/AssistedInjectInterceptor.php (1)

66-67: LGTM! Type parameter addition improves type safety.

The addition of <object> type parameter to MethodInvocation enhances type safety by explicitly indicating that the invocation operates on objects.

src/di/Injector.php Outdated Show resolved Hide resolved
Add a check in the Injector class to verify that the temporary directory is writable before proceeding with the class directory initialization. Introduced a new exception, DirectoryNotWritable, to handle cases where the directory is not writable, enhancing error handling and code robustness.
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

🧹 Outside diff range and nitpick comments (2)
src/di/Exception/DirectoryNotWritable.php (1)

9-11: Add documentation and default message

While the implementation is correct, consider adding:

  1. A PHPDoc block describing when this exception is thrown
  2. A constructor with a meaningful default message
+/**
+ * Exception thrown when a directory required for dependency injection cache
+ * is not writable by the application.
+ */
 class DirectoryNotWritable extends RuntimeException implements ExceptionInterface
 {
+    public function __construct(
+        string $message = 'The specified directory is not writable',
+        int $code = 0,
+        ?\Throwable $previous = null
+    ) {
+        parent::__construct($message, $code, $previous);
+    }
 }
src/di/Injector.php (1)

Line range hint 23-41: Consider extracting directory management into a separate service.

The Injector class currently handles multiple responsibilities including directory management. Consider extracting the directory handling logic into a dedicated service (e.g., ClassDirectoryManager) to:

  1. Improve separation of concerns
  2. Make directory management more testable
  3. Allow for different directory strategies
  4. Centralize directory-related error handling

This would make the Injector class more focused on its primary responsibility of dependency injection.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 158425d and ff8f66c.

📒 Files selected for processing (2)
  • src/di/Exception/DirectoryNotWritable.php (1 hunks)
  • src/di/Injector.php (2 hunks)
🔇 Additional comments (8)
src/di/Exception/DirectoryNotWritable.php (3)

1-6: LGTM: Proper file structure and namespace declaration

The file follows PSR-4 standards with proper strict types declaration for enhanced type safety.


7-8: LGTM: Clean import statement

The import is properly used and necessary for the class implementation.


9-11: Verify exception usage patterns

Let's verify how this exception is used across the codebase to ensure consistent error handling.

✅ Verification successful

Exception usage is consistent but lacks test coverage

The DirectoryNotWritable exception is used consistently in a single location within src/di/Injector.php to handle unwritable directory scenarios during dependency injection. The implementation follows good practices:

  • Extends RuntimeException and implements ExceptionInterface
  • Used in conjunction with proper directory permission check (is_writable)
  • Clear, single responsibility for handling directory write permission failures

However, the code comment @CodeCoverageIgnore suggests this error path isn't tested, which could be improved.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find usages of DirectoryNotWritable exception and their context

# Search for throw statements using this exception
echo "Searching for throw statements..."
rg "throw new DirectoryNotWritable" -B 2 -A 2

# Search for catch blocks handling this exception
echo "Searching for catch blocks..."
rg "catch \(DirectoryNotWritable" -B 2 -A 2

Length of output: 536


Script:

#!/bin/bash
# Let's verify if there are any other error handling patterns or related directory checks

# Search for related directory permission checks
echo "Searching for directory permission checks..."
rg "is_writable\(" -B 2 -A 2

# Search for similar exception patterns in the codebase
echo "Searching for similar RuntimeException usage..."
rg "extends RuntimeException" -B 1 -A 1

# Check if there are any tests for this exception
echo "Searching for tests related to DirectoryNotWritable..."
fd "test" --type f --exec rg "DirectoryNotWritable" -B 2 -A 2

Length of output: 1009

src/di/Injector.php (5)

9-9: LGTM: Import statement is correctly placed.

The import for DirectoryNotWritable exception is properly organized with other exception imports.


15-15: LGTM: Function import is correctly placed.

The import for is_writable function is properly organized with other function imports.


23-24: LGTM: Type safety improvement for $classDir property.

The property type has been strengthened to non-empty-string, ensuring the directory path is never empty at compile time.


Line range hint 30-32: LGTM: Improved type specification in docblock.

The parameter type specification is now more precise, clearly indicating valid input types for $module.


35-41: LGTM: Implemented directory writability check with specific exception.

The implementation follows the past review suggestion but improves upon it by:

  1. Using a specific DirectoryNotWritable exception instead of generic RuntimeException
  2. Adding proper type assertion for $classDir

@koriym koriym merged commit a00907d into 2.x Nov 28, 2024
44 checks passed
@koriym koriym deleted the optional-setter-injection branch November 28, 2024 17:02
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.

1 participant