3

I know there are a lot of questions about 'Area code is not set', but no one has yet answered the main question. How to find the file which caused this Exception?

In my case, I updated a lot of modules with thousand lines, and now I get this Exception...Magento 2 makes me cry :(

Thanks for any thoughts. :)

UPD: The error appeared after updating the Magento to 2.2

3
  • As per my experience this appears in setup file, and whenever we do setup upgarde magento tells module name which has this issue. This issue is resolved if we set area code in setup file. When are you getting this error can you tell that, on accessing the application or while setup upgrade.
    – arushi
    Oct 31, 2017 at 6:41
  • @arushi. This error appears after composer update/setup with new version of magento (2.2) when I use php bin/magento without parameters after the help line about setup:upgrade
    – spiilmusic
    Nov 1, 2017 at 6:45
  • @spiil on which operation you are getting above error? Nov 3, 2017 at 4:04

4 Answers 4

6

So. First, thanks to @SwAt.Be, he's pushed me to the right way. Second, Magento 2 DI debug is really sucks. I hope the guys from Magento ever fix it.

Preamble

Some of the core models requires Area to be set.

If you directly inject these models into your custom class constructor, and this class in turn is injected somewhere else, and some class of this chain is injected into the your custom Console Command class, then each run of the php bin/magento will cause 'Area code is not set'.

This is a specificity of Magento 2 Dependency Injection. In Developer mode it executes every constructor code of every injected class before real magento init. You can't see what happened at this moment (notice: it's possible when you manually run setup:di:compile)

How to debug

Just try to run setup:di:compile and try to fix all happened errors.

If it wont help:

  1. try to determine which of your custom modules are using Console Command

  2. try to disable injections one by one until the exception is disappear (check by the bin/magento execute)

    // file: MyNamespace/MyModule/Console/Command/ImportCommand.php
    public function __construct(
        //Import $import, // <-- Just my custom import model, that inject another model, that inject another model...that inject core model, that needs the Area to be set
        array $commands = []
    )
    {
        //$this->import = $import;
        $this->commands = $commands;
        parent::__construct();
    }
    
  3. Found a problem model? Great. Go to the next link of our chain and do p.2 until you'll find the core model, then go to the solution.

Solution

When you found the injection that cause this exception (This is usually a model), use the Factory of this model instead and create the model through the Factory method ->create() AFTER the $state->setAreaCode(smth); (below an example). Of course you can just made this with the first model in the chain (Import model in my case):

    // file: MyNamespace/MyModule/Console/Command/ImportCommand.php
    public function __construct(
        \Magento\Framework\App\State $state, 
        ImportFactory $importFactory, // <-- Just my custom import model, that inject another model, that inject another model...that inject core model, that needs the Area to be set
        array $commands = []
    )
    {
        try {
            $state->setAreaCode(\Magento\Framework\App\Area::AREA_ADMINHTML); // In my case I need the adminhtml area
        } catch (\Magento\Framework\Exception\LocalizedException $e) 
        {
            // nothing to do
        }
        $this->import = $importFactory->create();
        $this->commands = $commands;
        parent::__construct();
    }

but it's no good, because this error can be appear not only in the Console.

So I found the last model in the chain, and my fix looks like that:

// file: MyNamespace/MyModule/Model/Import/OrderImport.php
public function __construct(
    \Magento\Framework\App\State $state,
    \Magento\Sales\Api\Data\OrderInterfaceFactory $orderInterfaceFactory, // <-- this
    \Magento\Sales\Model\Service\CreditmemoServiceFactory $creditmemoServiceFactory // <-- and this
)
{
    try {
        $state->setAreaCode(\Magento\Framework\App\Area::AREA_GLOBAL);
    } catch (\Magento\Framework\Exception\LocalizedException $e) {
        // nothing to do
    }
    $this->orderInterface = $orderInterfaceFactory->create(); // <-- here
    $this->creditmemoService = $creditmemoServiceFactory->create(); // <-- and here
}

This answer does not claim to be correct, but this is what my investigation led me to.

Please feel free to comment and edit the answer.

It took me a very long time. I just hope it may helps someone.

Cheers!

1
  • 1
    Thank you for this! This problem has been bugging me for a day and with your help I fixed it. All I had to do in the end was change one injected class to the Factory version and create the original class.
    – Digitaq
    Mar 27, 2019 at 16:12
1
+50

Some module is setting an area code somewhere. Usually this is done in the console of a module.

A consoles makes a command that you can use in ssh but you want to define if that command is frontend of adminhtml. The way how you add them has changed.

In you app/code folder search for setAreaCode. People used to define them in their __construct function like this :

  public function __construct(State $state){
        $this->_state = $state;
$this->_state->setAreaCode(Area::AREA_ADMINHTML);
}

But that not good anymore. Now you need to define it within your execute() function

 public function __construct(State $state){
            $this->_state = $state;
    }

 protected function execute(
        InputInterface $input,
        OutputInterface $output
    )
    {

        $this->_state->setAreaCode(Area::AREA_ADMINHTML);
}

Since i don't have more information to work with this is the fastest way for you to debug it.

hope it helps

1
  • Yep, you're right! It can be caused only by the constructor of the Console Command class. Thank you. You've pushed me to some idea...
    – spiilmusic
    Nov 3, 2017 at 16:51
0

The only way, there are 4 types of installers Install/Upgrade data/schema. When you run php bin/magento setup:upgrade the last module in log will be the one which blow everything up. Then you must debug these files with emphasis on data install/upgrade files. There is no other way.

1
  • It happened before any module is showing. There is a part of log: ... Updating modules: Area code not set: Area code must be set before starting a session. ...
    – spiilmusic
    Nov 3, 2017 at 16:37
0

One thing is sure your question is wrong ,

but I can give you some hint how are code is define , how magento picks are code

when you perform some action admin or frontend magento automatically pick the are as adminhtml or frontend ,

but sometime your code is running by cron or some thing else individual script where no area is in the picture then you have to tell magento that which are is this

and at that time if you don't specify area then magento gives area code error

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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