0

After upgrading from Magento Open Source 2.4.6 to 2.4.7 custom PHP scripts that Bootstrap Magento 2 are failing to run with the error

PHP Fatal error:  Uncaught TypeError: Magento\ApplicationPerformanceMonitor\Plugin\ApplicationPerformanceMonitor::aroundLaunch(): Return value must be of type Magento\Framework\App\ResponseInterface, array returned in /var/www/dev/magento2/vendor/magento/module-application-performance-monitor/Plugin/ApplicationPerformanceMonitor.php:38

Bootstrap script is based on this example https://magento.stackexchange.com/a/76382/7863

public function launch()
    {
        $this->run();
        return $this->_response;
    }

If I dump $this->_response I get the correct output from my script, I need to return this as value of type Magento\Framework\App\ResponseInterface.

2 Answers 2

1

The aroundLaunch method in the Magento\ApplicationPerformanceMonitor\Plugin\ApplicationPerformanceMonitor plugin requires the turn type to be Magento\Framework\App\ResponseInterface. Therefore, the launch method in your custom PHP script must also return a value of type Magento\Framework\App\ResponseInterface.

Let's debug the issue:

  1. I assume your current launch method in the AbstractApp class (scripts/abstract.php) has the following content. Please note that I replaced the property from _response to response to utilize the constructor promotion property feature in PHP 8.
public function launch()
    {
        $this->run();
        return $this->response;
    }

Replace it with the following content:

public function launch()
{
    $this->run();

    if ($this->response instanceof \Magento\Framework\App\ResponseInterface) {
        echo '$this->response is instanceof \Magento\Framework\App\ResponseInterface'. "\n";
    } else {
        echo '$this->response is NOT instanceof \Magento\Framework\App\ResponseInterface'. "\n";
    }
    var_dump(get_class($this->response));
    var_dump($this->response);
    die;
    return $this->response;
}
  1. Edit the vendor/magento/module-application-performance-monitor/Plugin/ApplicationPerformanceMonitor.php file to add the following line at the beginning of the around Launch method:
echo 'triggered aroundLaunch ApplicationPerformanceMonitor plugin'. "\n";

Then run the script: php scripts/delete-category.php

Then provide with me the out.

Here is my output:

triggered aroundLaunch ApplicationPerformanceMonitor plugin
$this->response is instanceof \Magento\Framework\App\ResponseInterface
string(47) "Magento\Framework\App\Response\Http\Interceptor"
object(Magento\Framework\App\Response\Http\Interceptor)#140 (19) {
  ["metadata":protected]=>
  array(0) {
  }
  ["content":protected]=>
  string(0) ""
  ["version":protected]=>
  NULL
  ["headers":protected]=>
  NULL
  ["recommendedReasonPhrases":protected]=>
  array(64) {
    [100]=>
    string(8) "Continue"
    [101]=>
    string(19) "Switching Protocols"
    [102]=>
    string(10) "Processing"
    [200]=>
    string(2) "OK"
    [201]=>
    string(7) "Created"
    [202]=>
    string(8) "Accepted"
    [203]=>
    string(29) "Non-Authoritative Information"
    [204]=>
    string(10) "No Content"
    [205]=>
    string(13) "Reset Content"
    [206]=>
    string(15) "Partial Content"
    [207]=>
    string(12) "Multi-status"
    [208]=>
    string(16) "Already Reported"
    [226]=>
    string(7) "IM Used"
    [300]=>
    string(16) "Multiple Choices"
    [301]=>
    string(17) "Moved Permanently"
    [302]=>
    string(5) "Found"
    [303]=>
    string(9) "See Other"
    [304]=>
    string(12) "Not Modified"
    [305]=>
    string(9) "Use Proxy"
    [306]=>
    string(12) "Switch Proxy"
    [307]=>
    string(18) "Temporary Redirect"
    [308]=>
    string(18) "Permanent Redirect"
    [400]=>
    string(11) "Bad Request"
    [401]=>
    string(12) "Unauthorized"
    [402]=>
    string(16) "Payment Required"
    [403]=>
    string(9) "Forbidden"
    [404]=>
    string(9) "Not Found"
    [405]=>
    string(18) "Method Not Allowed"
    [406]=>
    string(14) "Not Acceptable"
    [407]=>
    string(29) "Proxy Authentication Required"
    [408]=>
    string(16) "Request Time-out"
    [409]=>
    string(8) "Conflict"
    [410]=>
    string(4) "Gone"
    [411]=>
    string(15) "Length Required"
    [412]=>
    string(19) "Precondition Failed"
    [413]=>
    string(17) "Content Too Large"
    [414]=>
    string(12) "URI Too Long"
    [415]=>
    string(22) "Unsupported Media Type"
    [416]=>
    string(21) "Range Not Satisfiable"
    [417]=>
    string(18) "Expectation Failed"
    [418]=>
    string(12) "I'm a teapot"
    [422]=>
    string(21) "Unprocessable Content"
    [423]=>
    string(6) "Locked"
    [424]=>
    string(17) "Failed Dependency"
    [425]=>
    string(9) "Too Early"
    [426]=>
    string(16) "Upgrade Required"
    [428]=>
    string(21) "Precondition Required"
    [429]=>
    string(17) "Too Many Requests"
    [431]=>
    string(31) "Request Header Fields Too Large"
    [444]=>
    string(34) "Connection Closed Without Response"
    [451]=>
    string(29) "Unavailable For Legal Reasons"
    [499]=>
    string(21) "Client Closed Request"
    [500]=>
    string(21) "Internal Server Error"
    [501]=>
    string(15) "Not Implemented"
    [502]=>
    string(11) "Bad Gateway"
    [503]=>
    string(19) "Service Unavailable"
    [504]=>
    string(15) "Gateway Timeout"
    [505]=>
    string(26) "HTTP Version not supported"
    [506]=>
    string(23) "Variant Also Negotiates"
    [507]=>
    string(20) "Insufficient Storage"
    [508]=>
    string(13) "Loop Detected"
    [510]=>
    string(12) "Not Extended"
    [511]=>
    string(31) "Network Authentication Required"
    [599]=>
    string(29) "Network Connect Timeout Error"
  }
  ["statusCode":protected]=>
  int(200)
  ["reasonPhrase":protected]=>
  NULL
  ["headersSent"]=>
  NULL
  ["contentSent":protected]=>
  bool(false)
  ["headersSentHandler":"Laminas\Http\PhpEnvironment\Response":private]=>
  NULL
  ["isRedirect":protected]=>
  bool(false)
  ["request":protected]=>
  object(Magento\Framework\App\Request\Http)#130 (5) {
    ["pathInfo"]=>
    string(0) ""
    ["requestString"]=>
    string(0) ""
    ["module"]=>
    NULL
    ["controller"]=>
    NULL
    ["action"]=>
    NULL
  }
  ["cookieManager":protected]=>
  object(Magento\Framework\Stdlib\Cookie\PhpCookieManager)#128 (4) {
    ["scope":"Magento\Framework\Stdlib\Cookie\PhpCookieManager":private]=>
    object(Magento\Framework\Stdlib\Cookie\CookieScope)#142 (4) {
      ["sensitiveCookieMetadata":"Magento\Framework\Stdlib\Cookie\CookieScope":private]=>
      NULL
      ["publicCookieMetadata":"Magento\Framework\Stdlib\Cookie\CookieScope":private]=>
      NULL
      ["cookieMetadata":"Magento\Framework\Stdlib\Cookie\CookieScope":private]=>
      NULL
      ["cookieMetadataFactory":"Magento\Framework\Stdlib\Cookie\CookieScope":private]=>
      object(Magento\Framework\Stdlib\Cookie\CookieMetadataFactory)#143 (1) {
        ["objectManager":"Magento\Framework\Stdlib\Cookie\CookieMetadataFactory":private]=>
        object(Magento\Framework\App\ObjectManager)#53 (0) {
        }
      }
    }
    ["reader":"Magento\Framework\Stdlib\Cookie\PhpCookieManager":private]=>
    object(Magento\Framework\Stdlib\Cookie\PhpCookieReader)#138 (0) {
    }
    ["logger":"Magento\Framework\Stdlib\Cookie\PhpCookieManager":private]=>
    object(Magento\Framework\Logger\LoggerProxy)#21 (2) {
      ["objectManager":"Magento\Framework\Logger\LoggerProxy":private]=>
      object(Magento\Framework\App\ObjectManager)#53 (0) {
      }
      ["logger":"Magento\Framework\Logger\LoggerProxy":private]=>
      NULL
    }
    ["httpHeader":"Magento\Framework\Stdlib\Cookie\PhpCookieManager":private]=>
    object(Magento\Framework\HTTP\Header)#147 (2) {
      ["_request":protected]=>
      object(Magento\Framework\App\Request\Http)#130 (5) {
        ["pathInfo"]=>
        string(0) ""
        ["requestString"]=>
        string(0) ""
        ["module"]=>
        NULL
        ["controller"]=>
        NULL
        ["action"]=>
        NULL
      }
      ["_converter":protected]=>
      object(Magento\Framework\Stdlib\StringUtils)#136 (0) {
      }
    }
  }
  ["cookieMetadataFactory":protected]=>
  object(Magento\Framework\Stdlib\Cookie\CookieMetadataFactory)#143 (1) {
    ["objectManager":"Magento\Framework\Stdlib\Cookie\CookieMetadataFactory":private]=>
    object(Magento\Framework\App\ObjectManager)#53 (0) {
    }
  }
  ["context":protected]=>
  object(Magento\Framework\App\Http\Context\Interceptor)#146 (6) {
    ["data":protected]=>
    array(0) {
    }
    ["default":protected]=>
    array(2) {
      ["website"]=>
      string(1) "0"
      ["customer_group"]=>
      int(0)
    }
    ["serializer":"Magento\Framework\App\Http\Context":private]=>
    object(Magento\Framework\Serialize\Serializer\Json)#129 (0) {
    }
    ["deploymentConfig":"Magento\Framework\App\Http\Context":private]=>
    NULL
    ["pluginList":"Magento\Framework\App\Http\Context\Interceptor":private]=>
    object(Magento\Framework\Interception\PluginList\PluginList)#156 (0) {
    }
    ["subjectType":"Magento\Framework\App\Http\Context\Interceptor":private]=>
    string(34) "Magento\Framework\App\Http\Context"
  }
  ["dateTime":protected]=>
  object(Magento\Framework\Stdlib\DateTime)#139 (0) {
  }
  ["sessionConfig":"Magento\Framework\App\Response\Http":private]=>
  object(Magento\Framework\Session\Config\ConfigInterface\Proxy)#152 (1) {
    ["i"]=>
    NULL
  }
  ["pluginList":"Magento\Framework\App\Response\Http\Interceptor":private]=>
  object(Magento\Framework\Interception\PluginList\PluginList)#156 (0) {
  }
  ["subjectType":"Magento\Framework\App\Response\Http\Interceptor":private]=>
  string(35) "Magento\Framework\App\Response\Http"
}
3
  • It seems that you modified the launch method. I tested the script shared by Luke Rodgers but it works as expected since the value of $this->response is object Magento\Framework\App\Response\Http\Interceptor, which is an instance of \Magento\Framework\App\ResponseInterface. I updated my answer to provide additional steps to debug this issue. Commented Apr 17, 2024 at 14:39
  • Thankyou for this, I will check my code. It is worth noting this is also an update from PHP8.2 to PHP8.3 Commented Apr 17, 2024 at 14:43
  • @paj I tested on PHP 8.2.11, but I don't think this matters. Could you provide me with the output with my suggestion? If necessary, I can use PHP 8.3 to verify it. Commented Apr 17, 2024 at 14:58
0

To return the data correctly using the Magento Bootstrap example here https://magento.stackexchange.com/a/76382/7863

Modify the launch method

public function launch()
{
    $this->_response->setContent($this->run());
    return $this->_response;

} 

Then retrieve your original custom data using

$data=$app->launch()->getContent();
5
  • It seems that something is wrong with your project. I tested the script shared by Luke Rodgers and don't need to create the response object manually and it works as expected. The value of $this->response is object Magento\Framework\App\Response\Http\Interceptor, which is an instance of \Magento\Framework\App\ResponseInterface. Commented Apr 17, 2024 at 14:43
  • Worth noting this is PHP8.3.6 Commented Apr 17, 2024 at 14:53
  • 1
    I tested on PHP 8.2.11, but I don't think this matters. Commented Apr 17, 2024 at 14:56
  • OK I have modified the original script quite a lot and it has ran in all versions of Magento up to 2.4.7. Using $this->_response->setContent($this->run()); seems to work for me now. Thankyou for your help. Commented Apr 17, 2024 at 14:58
  • I got it. If you still need to deep dive into this issue, I can provide you the clean content scripts based on Luke's post. Commented Apr 17, 2024 at 15:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.