-
Notifications
You must be signed in to change notification settings - Fork 9.4k
Description
Preconditions
Magento 2.1.3, PHP 5.6, Apache
- Create a Block that would throw an Exception while being rendered (in other words, throw an Exception from the template)
Basically, the following code in any .phtml file being rendered on frontend would do:
<?php throw new \Exception('your error message'); ?>
Steps to reproduce
- Open the page containing the Block which would throw an Exception while rendering.
Expected result
- Page gets rendered successfully (the erroneous block gets skipped).
- The file var/log/system.log contains the error message from the Exception thrown:
main.CRITICAL: your error message
Actual result
The corresponding file in var/report contains an unrelated error, making it hide to understand what exactly went wrong:
a:4:{i:0;s:37:"Object DOMDocument should be created.";i:1;s:12870:"#0 /var/www/html/magento/vendor/magento/framework/View/Element/UiComponent/Config/Reader.php(95): Magento\Framework\View\Element\UiComponent\Config\DomMerger->getDom() #1 /var/www/html/magento/vendor/magento/module-ui/Model/Manager.php(261): Magento\Framework\View\Element\UiComponent\Config\Reader->read() #2 /var/www/html/magento/vendor/magento/module-ui/Model/Manager.php(169): Magento\Ui\Model\Manager->prepare('layered.loading...') #3 /var/www/html/magento/vendor/magento/framework/View/Element/UiComponentFactory.php(139): Magento\Ui\Model\Manager->prepareData('layered.loading...') #4 /var/www/html/magento/vendor/magento/framework/View/Layout/Generator/UiComponent.php(125): Magento\Framework\View\Element\UiComponentFactory->create('layered.loading...', NULL, Array) #5 /var/www/html/magento/vendor/magento/framework/View/Layout/Generator/UiComponent.php(93): Magento\Framework\View\Layout\Generator\UiComponent->generateComponent(Object(Magento\Framework\View\Layout\Data\Structure), 'layered.loading...', Array, Object(Magento\Framework\View\Layout\Interceptor)) #6 /var/www/html/magento/vendor/magento/framework/View/Layout/GeneratorPool.php(86): Magento\Framework\View\Layout\Generator\UiComponent->process(Object(Magento\Framework\View\Layout\Reader\Context), Object(Magento\Framework\View\Layout\Generator\Context)) #7 /var/www/html/magento/vendor/magento/framework/View/Layout.php(327): Magento\Framework\View\Layout\GeneratorPool->process(Object(Magento\Framework\View\Layout\Reader\Context), Object(Magento\Framework\View\Layout\Generator\Context)) #8 /var/www/html/magento/vendor/magento/framework/View/Layout/Builder.php(129): Magento\Framework\View\Layout->generateElements() #9 /var/www/html/magento/vendor/magento/framework/View/Page/Builder.php(55): Magento\Framework\View\Layout\Builder->generateLayoutBlocks() #10 /var/www/html/magento/vendor/magento/framework/View/Layout/Builder.php(65): Magento\Framework\View\Page\Builder->generateLayoutBlocks() #11 /var/www/html/magento/vendor/magento/framework/View/Page/Config.php(187): Magento\Framework\View\Layout\Builder->build() #12 /var/www/html/magento/vendor/magento/framework/View/Page/Config.php(197): Magento\Framework\View\Page\Config->build() #13 /var/www/html/magento/vendor/magento/framework/App/View.php(170): Magento\Framework\View\Page\Config->publicBuild() #14 /var/www/html/magento/vendor/magento/framework/App/View.php(114): Magento\Framework\App\View->loadLayoutUpdates() #15 /var/www/html/magento/vendor/magento/module-catalog-search/Controller/Result/Index.php(90): Magento\Framework\App\View->loadLayout() #16 /var/www/html/magento/vendor/magento/framework/App/Action/Action.php(102): Magento\CatalogSearch\Controller\Result\Index->execute()...
This is not just a theoretical thing, such a situation may happen for a number of reasons, including but not limited to buggy customized code, incompatible or badly tested 3rd party extensions.
It might even be triggered by an unforeseen combination of actions by the merchant on an out-of-the-box Magento instance, as shown in #5323
This behaviour is not just strange and unexpected, it's harmful:
While "your error message" might still be contained in the system.log, you have face a bigger error in front of you with and have no reason to look into system.log.
Thus, the actual issue gets obscured by the more obviously shown and unrelated one, making the debugging process frustrating and time-consuming.
As a developer, I personally can get through this, but to a newbie merchant having installed a broken or incompatible module or theme such a situation may present a real challenge.
What actually happens here
The Exception being thrown by the Block gets catched here
The unset() prvents the block from further processing by Generator\Block, yes.
However, the block remains inside the $scheduledStructure. An additional $scheduledStructure->unsetElement() call might be appropriate here.
Further on, the scheduledStructure gets passed on to the Generator\UiComponent which happens to ignore element type completely.
Compare that to the Block generator which explicitly checks the element type to be compatible
If an identical additional check was performed in the UiComponent generator as well it would fix the issue reported here, as well.
