Вчера потратил полдня в попытках разобраться с причиной появления исключения в PHP-коде, а с утра в голову пришла мысль, что причиной был я сам. Вернее, использование мной отладчика в IDE PhpStorm для трассировки хода выполнения кода.
Условия возникновения ситуации — под катом.
Для начала, сообщение об ошибке:
Warning: Magento\Ui\TemplateEngine\Xhtml\Result::__toString(): Not yet implemented in /.../Xhtml/Result.php on line 97
Затем упомянутая в сообщении строка кода номер 97:
if ('noNamespaceSchemaLocation' === $name)
Как бы все прозрачно — при сравнении $name
преобразовывается в строку, что и приводит к исключению (мысль, что в стектрейсе в таком случае должен быть метод __toString()
для $name
приходит в голову чуть позже).
Вот сам метод:
public function __toString() { try { $templateRootElement = $this->getDocumentElement(); foreach ($templateRootElement->attributes as $name => $attribute) { if ('noNamespaceSchemaLocation' === $name) { $this->getDocumentElement()->removeAttributeNode($attribute); break; } } $templateRootElement->removeAttributeNS('http://www.w3.org/2001/XMLSchema-instance', 'xsi'); $this->compiler->compile($templateRootElement, $this->component, $this->component); $this->appendLayoutConfiguration(); $result = $this->compiler->postprocessing($this->template->__toString()); } catch (\Exception $e) { $this->logger->critical($e->getMessage()); $result = $e->getMessage(); } return $result; }
Тут уже несколько более кучеряво — присутствует блок try…catch, отлавливающий исключения. Но тоже никакого криминала: все, что работает — превращается компилятором в строку ($result = $this->compiler->postprocessing(...)
), что не работает — превращается в сообщение об ошибке ($result = $e->getMessage()
).
Я же под отладчиком в этом коде дохожу до if ('noNamespaceSchemaLocation' === $name)
, затем перехват исключения и $this->logger->critical($e->getMessage())
, затем необъяснимый перескок на \Magento\Backend\Model\Session\Interceptor::writeClose
, после выполнения которого обрыв работы приложения.
Всё. Все концы в воду — поток выполнения завершается, в браузере "HTTP ERROR 500", в логах сервера Result::__toString(): Not yet implemented
.
Причем достаточно просто войти в метод __toString()
под отладчиком — и выполнение приложения завершается вот таким вот причудливым образом. Если проскакивать его step over, то этот участок кода отрабатывает корректно. Так же не происходит в нем сбоя и при прогоне без отладчика.
Отладку я выполнял в среде PhpStorm 2017.1.3. IDE выводит множество полезной информации о работе приложения (stacktrace, woking vars, watchers):
И, безусловно, взаимодействует с работающим приложением.
Причин, почему происходит слет в этом случае, я так и не выяснил. Я все-таки web developer, а не разработчик IDE или интерпретатора.
"Многие вещи нам непонятны не потому, что наши понятия слабы; но потому, что сии вещи не входят в круг наших понятий." Козьма Прутков (с)
В своих попытках найти источник ошибки я полностью игнорировал влияние IDE на ход выполнения кода, что и вылилось в топтание по кругу в течение половины дня.
P.S.
Это — для всех тех, кому описанный выше случай сейчас кажется очевидным, и кто поделился своим опытом если и не на хабре, так в другом "интернете".
P.P.S.
Пока писал статью приложение под отладчиком стало отрабатывать, как от него и ожидается. В какой момент это произошло — непонятно (вчера была рабочая машина, сегодня — ноутбук, на котором я и воспроизводил ситуацию). Но сути самой статьи это не меняет — "при отладке учитывайте влияние IDE на работу приложения, особенно, если поведение приложения становится необъяснимым".
ссылка на оригинал статьи https://habrahabr.ru/post/329428/
Добавить комментарий