2

I'm fairly new to magento2 and trying to fix a broken extension.

I'm having a lot of trouble with stack traces, I'm not sure if it's just the way magento is or if it's because of reflection making it more abstract, but just by reading the stack I'm not able to figure out which file an error takes place in.

Example: If i go to the catalog and try to add a new product of the type this extension provides (it's a gift card extension),

It throws an error and dies.

The stack trace looks like this.

a:4:{i:0;s:112:"The requested component ("giftcard_price_selector") is not found. Before using, you must add the implementation.";i:1;s:8841:"#0 /path/to/magento/install/vendor/magento/module-ui/Model/Manager.php(207): Magento\Framework\View\Element\UiComponent\Config\Provider\Component\Definition->getComponentData('giftcard_price_...')
#1 /path/to/magento/install/vendor/magento/framework/View/Element/UiComponentFactory.php(187): Magento\Ui\Model\Manager->createRawComponentData('giftcard_price_...')
#2 /path/to/magento/install/vendor/magento/module-ui/Component/Form/Field.php(82): Magento\Framework\View\Element\UiComponentFactory->create('giftcard_price_...', 'giftcard_price_...', Array)
#3 /path/to/magento/install/vendor/magento/framework/View/Layout/Generator/UiComponent.php(148): Magento\Ui\Component\Form\Field->prepare()
#4 /path/to/magento/install/vendor/magento/framework/View/Layout/Generator/UiComponent.php(145): Magento\Framework\View\Layout\Generator\UiComponent->prepareComponent(Object(Magento\Ui\Component\Form\Field))
#5 /path/to/magento/install/vendor/magento/framework/View/Layout/Generator/UiComponent.php(145): Magento\Framework\View\Layout\Generator\UiComponent->prepareComponent(Object(Magento\Ui\Component\Container))
#6 /path/to/magento/install/vendor/magento/framework/View/Layout/Generator/UiComponent.php(145): Magento\Framework\View\Layout\Generator\UiComponent->prepareComponent(Object(Magento\Ui\Component\Form\Fieldset))
#7 /path/to/magento/install/vendor/magento/framework/View/Layout/Generator/UiComponent.php(126): Magento\Framework\View\Layout\Generator\UiComponent->prepareComponent(Object(Magento\Ui\Component\Form))
#8 /path/to/magento/install/vendor/magento/framework/View/Layout/Generator/UiComponent.php(93): Magento\Framework\View\Layout\Generator\UiComponent->generateComponent(Object(Magento\Framework\View\Layout\Data\Structure), 'product_form', Array, Object(Magento\Framework\View\Layout\Interceptor))
#9 /path/to/magento/install/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))
#10 /path/to/magento/install/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))
#11 /path/to/magento/install/vendor/magento/framework/View/Layout/Builder.php(129): Magento\Framework\View\Layout->generateElements()
#12 /path/to/magento/install/vendor/magento/framework/View/Page/Builder.php(55): Magento\Framework\View\Layout\Builder->generateLayoutBlocks()
#13 /path/to/magento/install/vendor/magento/framework/View/Layout/Builder.php(65): Magento\Framework\View\Page\Builder->generateLayoutBlocks()
#14 /path/to/magento/install/vendor/magento/framework/View/Layout.php(244): Magento\Framework\View\Layout\Builder->build()
#15 /path/to/magento/install/vendor/magento/framework/View/Layout.php(859): Magento\Framework\View\Layout->build()
#16 /path/to/magento/install/vendor/magento/module-backend/Model/View/Result/Page.php(59): Magento\Framework\View\Layout->getBlock('menu')
#17 /path/to/magento/install/vendor/magento/module-catalog/Controller/Adminhtml/Product/NewAction.php(71): Magento\Backend\Model\View\Result\Page->setActiveMenu('Magento_Catalog...')
#18 /path/to/magento/install/vendor/magento/framework/App/Action/Action.php(102): Magento\Catalog\Controller\Adminhtml\Product\NewAction->execute()
#19 /path/to/magento/install/vendor/magento/module-backend/App/AbstractAction.php(226): Magento\Framework\App\Action\Action->dispatch(Object(Magento\Framework\App\Request\Http))
#20 /path/to/magento/install/vendor/magento/framework/Interception/Interceptor.php(74): Magento\Backend\App\AbstractAction->dispatch(Object(Magento\Framework\App\Request\Http))
#21 /path/to/magento/install/vendor/magento/framework/Interception/Chain/Chain.php(70): Magento\Catalog\Controller\Adminhtml\Product\NewAction\Interceptor->___callParent('dispatch', Array)
#22 /path/to/magento/install/vendor/magento/framework/Interception/Chain/Chain.php(63): Magento\Framework\Interception\Chain\Chain->invokeNext('Magento\\Catalog...', 'dispatch', Object(Magento\Catalog\Controller\Adminhtml\Product\NewAction\Interceptor), Array, 'adminAuthentica...')
#23 /path/to/magento/install/vendor/magento/module-backend/App/Action/Plugin/Authentication.php(143): Magento\Framework\Interception\Chain\Chain->Magento\Framework\Interception\Chain\{closure}(Object(Magento\Framework\App\Request\Http))
#24 /path/to/magento/install/vendor/magento/framework/Interception/Chain/Chain.php(67): Magento\Backend\App\Action\Plugin\Authentication->aroundDispatch(Object(Magento\Catalog\Controller\Adminhtml\Product\NewAction\Interceptor), Object(Closure), Object(Magento\Framework\App\Request\Http))
#25 /path/to/magento/install/vendor/magento/framework/Interception/Interceptor.php(138): Magento\Framework\Interception\Chain\Chain->invokeNext('Magento\\Catalog...', 'dispatch', Object(Magento\Catalog\Controller\Adminhtml\Product\NewAction\Interceptor), Array, 'adminMassaction...')
#26 /path/to/magento/install/vendor/magento/module-backend/App/Action/Plugin/MassactionKey.php(33): Magento\Catalog\Controller\Adminhtml\Product\NewAction\Interceptor->Magento\Framework\Interception\{closure}(Object(Magento\Framework\App\Request\Http))
#27 /path/to/magento/install/vendor/magento/framework/Interception/Interceptor.php(142): Magento\Backend\App\Action\Plugin\MassactionKey->aroundDispatch(Object(Magento\Catalog\Controller\Adminhtml\Product\NewAction\Interceptor), Object(Closure), Object(Magento\Framework\App\Request\Http))
#28 /path/to/magento/install/var/generation/Magento/Catalog/Controller/Adminhtml/Product/NewAction/Interceptor.php(26): Magento\Catalog\Controller\Adminhtml\Product\NewAction\Interceptor->___callPlugins('dispatch', Array, Array)
#29 /path/to/magento/install/vendor/magento/framework/App/FrontController.php(55): Magento\Catalog\Controller\Adminhtml\Product\NewAction\Interceptor->dispatch(Object(Magento\Framework\App\Request\Http))
#30 /path/to/magento/install/vendor/magento/framework/Interception/Interceptor.php(74): Magento\Framework\App\FrontController->dispatch(Object(Magento\Framework\App\Request\Http))
#31 /path/to/magento/install/vendor/magento/framework/Interception/Chain/Chain.php(70): Magento\Framework\App\FrontController\Interceptor->___callParent('dispatch', Array)
#32 /path/to/magento/install/vendor/magento/framework/Interception/Interceptor.php(138): Magento\Framework\Interception\Chain\Chain->invokeNext('Magento\\Framewo...', 'dispatch', Object(Magento\Framework\App\FrontController\Interceptor), Array, 'install')
#33 /path/to/magento/install/vendor/magento/framework/Module/Plugin/DbStatusValidator.php(69): Magento\Framework\App\FrontController\Interceptor->Magento\Framework\Interception\{closure}(Object(Magento\Framework\App\Request\Http))
#34 /path/to/magento/install/vendor/magento/framework/Interception/Interceptor.php(142): Magento\Framework\Module\Plugin\DbStatusValidator->aroundDispatch(Object(Magento\Framework\App\FrontController\Interceptor), Object(Closure), Object(Magento\Framework\App\Request\Http))
#35 /path/to/magento/install/var/generation/Magento/Framework/App/FrontController/Interceptor.php(26): Magento\Framework\App\FrontController\Interceptor->___callPlugins('dispatch', Array, Array)
#36 /path/to/magento/install/vendor/magento/framework/App/Http.php(135): Magento\Framework\App\FrontController\Interceptor->dispatch(Object(Magento\Framework\App\Request\Http))
#37 /path/to/magento/install/vendor/magento/framework/App/Bootstrap.php(258): Magento\Framework\App\Http->launch()
#38 /path/to/magento/install/index.php(39): Magento\Framework\App\Bootstrap->run(Object(Magento\Framework\App\Http))

Now, from this trace, I can clearly see that some page in the extension is referencing a component called giftcard_price_selector, and if i search the source of the extension, i see it referenced in a couple of places.

My question to you is, how do i figure out which place it is?

I see that a page is adding a field, which caused magento's internal UI component factory to create a price selector (I assume this is probably a drop-down or something, I'm not really sure.) which is causing the error, but i can't seem to figure out which file it's actually happening in.

Part of this is me wanting to know the answer, but if you post an answer and could give a brief overview of how you got the answer so I can learn myself, it would be greatly appreciated

  • Is there a .xml file with: <uiComponent name="giftcard_price_selector"/> in it (there could be a space before the last / also)? Can you find a file like this: ModuleDir/view/adminhtml/ui_component/giftcard_price_selector.xml? – bassplayer7 Dec 27 '16 at 14:53
  • nope, all i see in that directory are giftcard_giftcard_listing.xml and giftcard_template_listing.xml, neither of which contain giftcard_price_selector or giftcard.price.selector (which is what the block was initially declared as) – Zachary Craig Dec 27 '16 at 15:00
  • At this point, I'm not aware of a way to use a UI Component without declaring it. Perhaps the dev neglected to include that xml file? When you say that you "see it referenced in a couple of places", what does that mean? Could you provide a few examples? – bassplayer7 Dec 27 '16 at 15:05
  • Well, when i did a search for it in the source code, i see it in 12 different places. it's in the Block\Adminhtml\Catalog\Product\Edit\Tag\Attributes\PriceSelectorRender.php file, in the context of the getPrices method returning $this->getProduct()->getData('giftcard_price_selector'), and the Block\Product\GiftCard.php returning return explode(',',$product->getData('giftcard_price_selector')); for getSelectorPrice(), and the setup file in Setup\InstallData.php, which adds an attribute called giftcard_price_selector, there's too much for comments to fit is. do you want to use IM? – Zachary Craig Dec 27 '16 at 15:09
  • Interesting. I've not done much work with M2's attributes and rendering - which uses UI Components. However, in Setup\InstallData.php, what is the 'type' of the 'giftcard_price_selector' attribute? Or by chance the type is actually: giftcard_price_selector? – bassplayer7 Dec 27 '16 at 15:36
2

From what I understand, the issue should be in a layout.xml file, as that is how UiComponents are included. I would look in your module's catalog_product_new.xml file, as that corresponds to the controller name (Magento\Catalog\Controller\Adminhtml\Product\NewAction).

That file isn't actually in the stack trace, but Magento reads it from the filesystem to build the tree of layout blocks and containers. In Magento 2, each layout.xml file corresponds to a specific handle, which is a term for a set of layout instructions. Typically, the handle corresponds to a action URL (frontname/controllerFolder/actionName). In this case, the front name was catalog, the controller sub-folder was product, and the referenced controller class (which can be called the action class) was NewController, so I would look inside the view/adminhtml/layout/catalog_product_new.xml file.

Welcome to Magento. Please let me know if anything I said doesn't make sense or needs clarification.

  • I don't actually see a catalog_product_new.xml. I searched the source for all the catalog_product xmls and got /view/adminhtml/layout/giftcard_catalog_product_edit.xml, /view/base/layout/catalog_product_prices.xml, and /view/frontend/layout/catalog_product_view_type_giftcard.xml – Zachary Craig Dec 27 '16 at 14:28
  • OK, it looks like the previous developer broke with Magento convention and added their own handles for multiple requests. I'd look in the adminhtml and base ones. – tjons Dec 27 '16 at 14:32
  • I noticed when he declared the price selector WYSIWYG form that the second argument, which i assume is the name, was giftcard.price.selector not giftcard_price_selector, do you think maybe that's the problem? I'm waiting on it to compile to check – Zachary Craig Dec 27 '16 at 14:52
  • Nope, that didn't fix it either :/ – Zachary Craig Dec 27 '16 at 15:05
  • I'm not super familiar with UiComponents (yet), but the error looks like the issue is with the component itself (like it's missing) rather than the layout. Adding your custom code to the question, or creating a new one (since this one was more about how to debug) is probably a better bet... If you do create a new question, please ping me with the link here and I'll take a look... – tjons Dec 27 '16 at 15:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.