И не предоставлю. Т.к. желание разобраться прямо противоречит посылу публикации:
"при отладке учитывайте влияние IDE на работу приложения, особенно, если поведение приложения становится необъяснимым"
Еще раз, суть публикации не в том, чтобы выяснить причину сбоя, а в том, чтобы показать, что бывают сбои, не относящиеся к решаемой проблеме. Я и так вижу, что изложение перпендикулярно поставленной задаче, а вы хотите, чтобы я еще усугубил все стектрейсом?
Вы привыкли докапываться до сути, а суть в том, что "под отладчиком почему-то выполняются другие ветки в рантайме PHP". Все, это она и есть. И стектрейс вам это мешает видеть, а не помогает.
О! Так вот и я об этом же!!! И эти ветки, в общем-то, могут иметь слабое отношение к сути решаемой проблемы (неверный набор данных в БД в моем случае). Достаточно проверить, что без трассировки код выполняется без ошибок и забить на те ошибки, которые вылетают при трассировке. Ибо, как вы верно заметили "под отладчиком почему-то выполняются другие ветки в рантайме PHP"
Да, я использую php7. Спасибо за попытки решить эту проблему, но я не ищу причину сбоя при отладке. У меня проблема в другом была — данные в БД лежали "неожиданные". Просто при трассировке я свернул на эту ошибку, думая, что это ошибка приложения, а не ошибка отладочного окружения.
Если бы я ее проигнорил, я бы на полдня раньше вышел на то, что мне нужно (ошибка в данных в БД).
Я как бы пытался этой статьей сформулировать мысль, что не все ошибки связаны с разрабатываемым приложением. Некоторые можно просто игнорить. Видно у меня плохо получилось :(
Я остаюсь в процессе отладки после возникновения ошибки — не думаю, что при падении процесса у меня закрывалась бы пользовательская сессиия (\Magento\Backend\Model\Session\Interceptor::writeClose).
А-а, это структура кода для класса \Magento\Ui\TemplateEngine\Xhtml\Result — properties, methods, const,… Просто анализ текста, к runtime'у отношения не имеет.
Не обратил внимание на тройное равенство. Спасибо.
Я тоже грешил на watchers изначально. Пока писал статью проверил эту версию — нет, watchers не при делах. Эта же самая ситуация повторялась и при пустом списке watchers.
Это Magento'вский код (framework'а). И try...catch работает — отлавливает исключение, выброшенное обработчиком ошибок. В самом try...catch в методе __toString() нет ничего криминального, но проблема в том, что исключение, на которое ругается интерпретатор, проскакивает за рамки try...catch. Я обернул try...catch еще несколько раз — каждый catch отрабатывает, а на выходе из последнего опять та же самая ошибка.
Если закомментировать строку $msg = $e->getMessage(); в каком-то из catch'ей, то перехват исключений будет идти до этого catch'а, потом перескок на return 'done';(с пропуском оставшихся catch'ей) и потом все равно та же самая ошибка. Это под отладчиком. Без отладчика код отрабатывает без ошибок.
Интересный способ. В Magento 2 используется генерация промежуточного кода для плагинов и использования нагенеренного вместо оригинала в собственном IoC-контейнере. Но если использовать оригинал напрямую (через new), а не через DI, то будет задействован оригинальный код. Мне кажется, что это достаточно удачный компромисс. Я во главу угла ставлю удобство отладки, особенно, когда имеешь дело с незнакомым кодом (а незнакомым становится даже собственный код, спустя какое-то время). Поэтому мне бы хотелось как можно меньше иметь подобного нагенеренного кода в приложении. Но так как подобный подход (плагины в Magento 2 или описанные Forwarding decorators) дает очень хорошую гибкость при независимой модульной разработке сложных систем, то, похоже, что так или иначе он будет использоваться.
Существующие в Magento 2 плагины позволяют оборачивать (before/after/around) любой публичный метод любого класса, создаваемого в IoC-контейнере, и выстраивать конвейеры из подобных «оберток» на основании зависимостей между модулями, в которых эти «обертки» объявлены. При удалении модуля соответствующая обертка выбывает из конвейера, при добавлении модуля — встраивается в соотв. место конвейра. Мне кажется это более удачный подход, чем выстраивание цепочек наследования (особенно, если зависимости между модулями не линейные, а древовидные), т.к. «обертки» полностью независимы друг от друга с точки зрения наследования. Если бы я обдумывал архитектуру приложения, я бы шел по этому пути (оборачивание отдельных методов и использование через DI, а не forwarding decorators).
На мой взгляд, победят те способы, которые дадут возможность разработчику наиболее безболезненно оперировать собственным, чужим и сгенеренным кодом, сопоставлять оригинальный код и все его модификации, ориентироваться в модулях и их зависимостях. Мне кажется, что это все-таки функционал уровня фреймворка/платформы, чем отдельная библиотека, подключаемая к любому проекту, т.к. сама кодогенерация зависит от модульной архитектуры приложения, которая задается фреймворком/платформой.
Это обработчик ошибок Magento'вский. Он упаковал ошибку в исключение и пробросил далее. Вся информация об ошибке, которая ему доступна, изложена в сообщении об ошибке, которую я привел в самом начале:
(сожалею, что придется прокручивать, но иначе концы строк режутся)
Сама ошибка возникает при проходе отладчиком по коду метода Result::__toString() и не возникает, если проскакивать через него (step over).
Если это и runtime, то никак не самого приложения, а совокупности всех компонентов среды отладки. Вот о том и публикация. Step in — есть ошибка, step over — нет ее. И искать строчку "Not yet implemented" нужно не только в "исходниках PHP", но и в исходниках xdebug, и в исходниках IDE.
А вот с этого места можно поподробнее, что именно вам с стектрейсе сказало, что это "warning рантайма, отловленный фреймворком и преобразованный в исключение"?
Ну и как нам поможет в этом случае "правильный" стектрейс? В нем зафиксировано только то, что я вижу в IDE. Или есть еще какой-то, "более правильный" стектрейс в месте про которое мало кто знает? В таком случае, поделитесь тайным знанием, коллега.
Не совсем так. Через IDE выставляются breakpoints, т.е., именно IDE запрашивает у xdebug'а ту или иную информацию. А breakpoints выставляет разработчик, как и трассировку по шагам выполняет также разработчик. Как я отметил, при "перескоке" через код (step over) поведение приложения под отладкой одно, при входе в проблемный метод (step in) — другое. Т.е., в конце-концов все упирается в разработчика. Учитывает ли он влияние всех компонентов отладочного ансамбля или на какие-то "забил".
А заголовок я все-таки подправлю — сам PhpStorm тут не при делах.
А каким образом предоставленный стектрейс относится к выводу "под отладчиком почему-то выполняются другие ветки в рантайме PHP"?
И не предоставлю. Т.к. желание разобраться прямо противоречит посылу публикации:
"при отладке учитывайте влияние IDE на работу приложения, особенно, если поведение приложения становится необъяснимым"
Еще раз, суть публикации не в том, чтобы выяснить причину сбоя, а в том, чтобы показать, что бывают сбои, не относящиеся к решаемой проблеме. Я и так вижу, что изложение перпендикулярно поставленной задаче, а вы хотите, чтобы я еще усугубил все стектрейсом?
Вы привыкли докапываться до сути, а суть в том, что "под отладчиком почему-то выполняются другие ветки в рантайме PHP". Все, это она и есть. И стектрейс вам это мешает видеть, а не помогает.
О! Так вот и я об этом же!!! И эти ветки, в общем-то, могут иметь слабое отношение к сути решаемой проблемы (неверный набор данных в БД в моем случае). Достаточно проверить, что без трассировки код выполняется без ошибок и забить на те ошибки, которые вылетают при трассировке. Ибо, как вы верно заметили "под отладчиком почему-то выполняются другие ветки в рантайме PHP"
Да, я использую php7. Спасибо за попытки решить эту проблему, но я не ищу причину сбоя при отладке. У меня проблема в другом была — данные в БД лежали "неожиданные". Просто при трассировке я свернул на эту ошибку, думая, что это ошибка приложения, а не ошибка отладочного окружения.
Если бы я ее проигнорил, я бы на полдня раньше вышел на то, что мне нужно (ошибка в данных в БД).
Я как бы пытался этой статьей сформулировать мысль, что не все ошибки связаны с разрабатываемым приложением. Некоторые можно просто игнорить. Видно у меня плохо получилось :(
Я остаюсь в процессе отладки после возникновения ошибки — не думаю, что при падении процесса у меня закрывалась бы пользовательская сессиия (
\Magento\Backend\Model\Session\Interceptor::writeClose).А-а, это структура кода для класса
\Magento\Ui\TemplateEngine\Xhtml\Result— properties, methods, const,… Просто анализ текста, к runtime'у отношения не имеет.Не обратил внимание на тройное равенство. Спасибо.
Я тоже грешил на watchers изначально. Пока писал статью проверил эту версию — нет, watchers не при делах. Эта же самая ситуация повторялась и при пустом списке watchers.
А то, что без отладчика этот код отрабатывает, а под отладкой сбоит — ничего не символизирует?
Это Magento'вский код (framework'а). И try...catch работает — отлавливает исключение, выброшенное обработчиком ошибок. В самом try...catch в методе
__toString()нет ничего криминального, но проблема в том, что исключение, на которое ругается интерпретатор, проскакивает за рамки try...catch. Я обернул try...catch еще несколько раз — каждый catch отрабатывает, а на выходе из последнего опять та же самая ошибка.Если закомментировать строку
$msg = $e->getMessage();в каком-то из catch'ей, то перехват исключений будет идти до этого catch'а, потом перескок наreturn 'done';(с пропуском оставшихся catch'ей) и потом все равно та же самая ошибка. Это под отладчиком. Без отладчика код отрабатывает без ошибок.В какой же?
Интересный способ. В Magento 2 используется генерация промежуточного кода для плагинов и использования нагенеренного вместо оригинала в собственном IoC-контейнере. Но если использовать оригинал напрямую (через new), а не через DI, то будет задействован оригинальный код. Мне кажется, что это достаточно удачный компромисс. Я во главу угла ставлю удобство отладки, особенно, когда имеешь дело с незнакомым кодом (а незнакомым становится даже собственный код, спустя какое-то время). Поэтому мне бы хотелось как можно меньше иметь подобного нагенеренного кода в приложении. Но так как подобный подход (плагины в Magento 2 или описанные Forwarding decorators) дает очень хорошую гибкость при независимой модульной разработке сложных систем, то, похоже, что так или иначе он будет использоваться.
Существующие в Magento 2 плагины позволяют оборачивать (before/after/around) любой публичный метод любого класса, создаваемого в IoC-контейнере, и выстраивать конвейеры из подобных «оберток» на основании зависимостей между модулями, в которых эти «обертки» объявлены. При удалении модуля соответствующая обертка выбывает из конвейера, при добавлении модуля — встраивается в соотв. место конвейра. Мне кажется это более удачный подход, чем выстраивание цепочек наследования (особенно, если зависимости между модулями не линейные, а древовидные), т.к. «обертки» полностью независимы друг от друга с точки зрения наследования. Если бы я обдумывал архитектуру приложения, я бы шел по этому пути (оборачивание отдельных методов и использование через DI, а не forwarding decorators).
На мой взгляд, победят те способы, которые дадут возможность разработчику наиболее безболезненно оперировать собственным, чужим и сгенеренным кодом, сопоставлять оригинальный код и все его модификации, ориентироваться в модулях и их зависимостях. Мне кажется, что это все-таки функционал уровня фреймворка/платформы, чем отдельная библиотека, подключаемая к любому проекту, т.к. сама кодогенерация зависит от модульной архитектуры приложения, которая задается фреймворком/платформой.
Это обработчик ошибок Magento'вский. Он упаковал ошибку в исключение и пробросил далее. Вся информация об ошибке, которая ему доступна, изложена в сообщении об ошибке, которую я привел в самом начале:

(сожалею, что придется прокручивать, но иначе концы строк режутся)
Сама ошибка возникает при проходе отладчиком по коду метода
Result::__toString()и не возникает, если проскакивать через него (step over).Если это и runtime, то никак не самого приложения, а совокупности всех компонентов среды отладки. Вот о том и публикация. Step in — есть ошибка, step over — нет ее. И искать строчку "Not yet implemented" нужно не только в "исходниках PHP", но и в исходниках xdebug, и в исходниках IDE.
А вот с этого места можно поподробнее, что именно вам с стектрейсе сказало, что это "warning рантайма, отловленный фреймворком и преобразованный в исключение"?
А зачем вам стектрейс в рамках данной публикации? Он как-то что-то изменил?
Спасибо за совет, коллега. Отключил

opcache— ситуация на рабочей машине воспроизводится и при отключенном кэше:Ну и как нам поможет в этом случае "правильный" стектрейс? В нем зафиксировано только то, что я вижу в IDE. Или есть еще какой-то, "более правильный" стектрейс в месте про которое мало кто знает? В таком случае, поделитесь тайным знанием, коллега.
Может быть потому, что трассировку стека можно посмотреть из самого IDE?
Вот вам трассировка стека из исключения в логе web-сервера:
[Thu May 25 12:59:05.128623 2017] [:error] [pid 6492] [client 192.168.4.111:57021] PHP Fatal error: Method Magento\\Ui\\TemplateEngine\\Xhtml\\Result::__toString() must not throw an exception, caught Exception: Warning: Magento\\Ui\\TemplateEngine\\Xhtml\\Resu lt::__toString(): Not yet implemented in /mnt/hard/prj/mobi_app_generic_mage2/work/vendor/magento/module-ui/TemplateEngine/Xhtml/Result.php on line 107 in /mnt/hard/prj/mobi_app_generic_mage2/work/vendor/magento/module-ui/Component/Wrapper/UiComponent.php on li ne 0, referer: http://mage2.local.host.com/admin/admin/dashboard/ [Thu May 25 12:59:05.128659 2017] [:error] [pid 6492] [client 192.168.4.111:57021] PHP Stack trace:, referer: http://mage2.local.host.com/admin/admin/dashboard/ [Thu May 25 12:59:05.128671 2017] [:error] [pid 6492] [client 192.168.4.111:57021] PHP 1. {main}() /mnt/hard/prj/mobi_app_generic_mage2/work/index.php:0, referer: http://mage2.local.host.com/admin/admin/dashboard/ ... [Thu May 25 12:59:05.128944 2017] [:error] [pid 6492] [client 192.168.4.111:57021] PHP 53. Magento\\Framework\\View\\Layout->_renderUiComponent($name = *uninitialized*) /mnt/hard/prj/mobi_app_generic_mage2/work/vendor/magento/framework/View/Layout.php:516, referer: http://mage2.local.host.com/admin/admin/dashboard/ [Thu May 25 12:59:05.128949 2017] [:error] [pid 6492] [client 192.168.4.111:57021] PHP 54. Magento\\Framework\\View\\Element\\AbstractBlock->toHtml() /mnt/hard/prj/mobi_app_generic_mage2/work/vendor/magento/framework/View/Layout.php:555, referer: http://mage2.local.host.com/admin/admin/dashboard/ [Thu May 25 12:59:05.128954 2017] [:error] [pid 6492] [client 192.168.4.111:57021] PHP 55. Magento\\Ui\\Component\\Wrapper\\UiComponent->_toHtml() /mnt/hard/prj/mobi_app_generic_mage2/work/vendor/magento/framework/View/Element/AbstractBlock.php:659, referer: http://mage2.local.host.com/admin/admin/dashboard/а вот из IDE:

Обратите внимание на стрелки — указанного вызова в стектрейсе в исключении из лога нет, а на самом деле — есть.
Не совсем так. Через IDE выставляются breakpoints, т.е., именно IDE запрашивает у xdebug'а ту или иную информацию. А breakpoints выставляет разработчик, как и трассировку по шагам выполняет также разработчик. Как я отметил, при "перескоке" через код (step over) поведение приложения под отладкой одно, при входе в проблемный метод (step in) — другое. Т.е., в конце-концов все упирается в разработчика. Учитывает ли он влияние всех компонентов отладочного ансамбля или на какие-то "забил".
А заголовок я все-таки подправлю — сам PhpStorm тут не при делах.
Ты был когда-нибудь маленький?
Чем-то напомнило — https://www.parser.ru/