Тонкости отладки или Как (не)убить полдня с PhpStorm

от автора

Вчера потратил полдня в попытках разобраться с причиной появления исключения в PHP-коде, а с утра в голову пришла мысль, что причиной был я сам. Вернее, использование мной отладчика в IDE PhpStorm для трассировки хода выполнения кода.

image

Условия возникновения ситуации — под катом.

Для начала, сообщение об ошибке:

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):

image

И, безусловно, взаимодействует с работающим приложением.

Причин, почему происходит слет в этом случае, я так и не выяснил. Я все-таки web developer, а не разработчик IDE или интерпретатора.

"Многие вещи нам непонятны не потому, что наши понятия слабы; но потому, что сии вещи не входят в круг наших понятий." Козьма Прутков (с)

В своих попытках найти источник ошибки я полностью игнорировал влияние IDE на ход выполнения кода, что и вылилось в топтание по кругу в течение половины дня.

P.S.
Это — для всех тех, кому описанный выше случай сейчас кажется очевидным, и кто поделился своим опытом если и не на хабре, так в другом "интернете".

P.P.S.
Пока писал статью приложение под отладчиком стало отрабатывать, как от него и ожидается. В какой момент это произошло — непонятно (вчера была рабочая машина, сегодня — ноутбук, на котором я и воспроизводил ситуацию). Но сути самой статьи это не меняет — "при отладке учитывайте влияние IDE на работу приложения, особенно, если поведение приложения становится необъяснимым".

ссылка на оригинал статьи https://habrahabr.ru/post/329428/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *