Skip to content

Calling Api Interface from Module Install triggers Exception that Area Code is not set #1405

@Vinai

Description

@Vinai

I've run into a problem while writing a small module to play some more with the service layer API.
I'm trying to add attribute options via Magento\Eav\Api\AttributeOptionManagementInterface::add().

This fails because no area is set while running bin/magento setup:upgrade.
Not sure if I'm doing anything wrong. I would expect this to work, since the setup class is using part of the "official" exposed interface of the Magento_Eav module.

Here is the call stack as far as I can see.

Magento\Eav\Api\AttributeOptionManagementInterface::add() causes the event catalog_entity_attribute_save_before to be dispatched as follows:

        $attribute->setOption($options);
        try {
            $this->resourceModel->save($attribute);
        } catch (\Exception $e) {
            throw new StateException(__('Cannot save attribute %1', $attributeCode));
        }

The resource model in this case is an instance of Magento\Eav\Model\Resource\Entity\Attribute

This event has an observer registered, namely Magento\Weee\Model\Observer.
What follows now is a series of dependency resolutions by the object manager.

Magento\Weee\Model\Observer depends on Magento\Tax\Helper\Data
Magento\Tax\Helper\Data depends on Magento\Tax\Api\TaxCalculationInterface
The preference for Magento\Tax\Api\TaxCalculationInterface is Magento\Tax\Model\TaxCalculation
Magento\Tax\Model\TaxCalculation is dependent on Magento\Tax\Model\Calculation
Magento\Tax\Model\Calculation is dependent on Magento\Customer\Model\Session
Magento\Customer\Model\Session is dependent on Magento\Framework\Session\Generic
Magento\Framework\Session\Generic extends from \Magento\Framework\Session\SessionManager
Magento\Framework\Session\SessionManager depends on \Magento\Framework\App\State

So far so good, but in the constructor the session manager calls $this->start():

Magento\Framework\Session\SessionManager::__construct() calls $this->start()
Magento\Framework\Session\SessionManager::start() calls Magento\Framework\App\State::getAreaCode()

Here is the method in question:

    public function getAreaCode()
    {
        if (!isset($this->_areaCode)) {
            throw new \Magento\Framework\Exception\LocalizedException(
                new \Magento\Framework\Phrase('Area code is not set')
            );
        }
        return $this->_areaCode;
    }

Now the problem is that $this->_areaCode is not set.

Summary: When running bin/magento the area code is not set on the app state instance.
This causes an exception while the session is started.

Not sure where the bug lies: the session being started while bin/magento is being executed from the command line or the app area not being set.
I can imagine the same problem cropping up in different API service layer calls, too, since this seems to be a low level issue.

Adding the attribute options via the eav setup class, or via attribute models and collections works like a charm, however I'm doing the exercise to practice how to do things the right way and use the service layer instead.

PS: In case it's helpful, I've pushed the code that calls the API service layer to github: https://github.com/vinai/VinaiKopp_EavOptionSetup

If you think it is useful I'd be happy to add the module install that triggers the error to this issue thread, too.

Metadata

Metadata

Assignees

Labels

Issue: Clear DescriptionGate 2 Passed. Manual verification of the issue description passedIssue: ConfirmedGate 3 Passed. Manual verification of the issue completed. Issue is confirmedIssue: Format is not validGate 1 Failed. Automatic verification of issue format is failedIssue: Ready for WorkGate 4. Acknowledged. Issue is added to backlog and ready for developmentbug report

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions