Skip to content

2.4.5 - Interceptor code generation fails on Union return types #39611

Closed
@Skullsneeze

Description

@Skullsneeze

Summary

Similar to the issue described in #39502 code generation for interceptors also fails when union return types are used (eg. int|string). In the current 2.4 develop branch this is already refactored, and the responsible logic is moved to lib/internal/Magento/Framework/GetReflectionMethodReturnTypeValueTrait.php. However, for 2.4.5-p10, this is still an existing issue.

Examples

Create a new class which extends \Magento\Framework\App\ActionInterface. In the implemented execute() method add the return types to the method signature:

public function execute(): ResponseInterface|Json|ResultInterface

Run the setup:di:compile command.

You should now receive an error when the Interceptor code for the class is generated.

Call to undefined method ReflectionUnionType::getName() in vendor/magento/framework/Interception/Code/Generator/Interceptor.php

Proposed solution

The following patch applies a change similar to the fix done in the issue #39502. The original commit was e4d1043

Patch:

diff --git a/vendor/magento/framework/Interception/Code/Generator/Interceptor.php b/vendor/magento/framework/Interception/Code/Generator/Interceptor.php
--- a/vendor/magento/framework/Interception/Code/Generator/Interceptor.php
+++ b/vendor/magento/framework/Interception/Code/Generator/Interceptor.php
@@ -212,10 +212,17 @@
         $returnTypeValue = null;
         $returnType = $method->getReturnType();
         if ($returnType) {
-            $returnTypeValue = ($returnType->allowsNull() ? '?' : '');
-            $returnTypeValue .= ($returnType->getName() === 'self')
-                ? $this->_getFullyQualifiedClassName($method->getDeclaringClass()->getName())
-                : $returnType->getName();
+            if ($returnType instanceof \ReflectionUnionType) {
+                $returnTypeValue = implode('|', $returnType->getTypes());
+            } elseif ($returnType->getName() === 'self') {
+                $returnTypeValue = $this->_getFullyQualifiedClassName($method->getDeclaringClass()->getName());
+            } else {
+                $returnTypeValue = $returnType->getName();
+            }
+
+            if ($returnType->allowsNull()) {
+                $returnTypeValue = "?$returnTypeValue";
+            }
         }
 
         return $returnTypeValue;

Release note

No response

Triage and priority

  • Severity: S0 - Affects critical data or functionality and leaves users without workaround.
  • Severity: S1 - Affects critical data or functionality and forces users to employ a workaround.
  • Severity: S2 - Affects non-critical data or functionality and forces users to employ a workaround.
  • Severity: S3 - Affects non-critical data or functionality and does not force users to employ a workaround.
  • Severity: S4 - Affects aesthetics, professional look and feel, “quality” or “usability”.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Triage: Dev.ExperienceIssue related to Developer Experience and needs help with Triage to Confirm or Reject it

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions