In production environment there is an error logged in exception log continuosly
[2018-01-05 08:19:16] main.CRITICAL: Area code not set: Area code must be set before starting a session. {"exception":"[object] (Magento\\Framework\\Exception\\SessionException(code: 0): Area code not set: Area code must be set before starting a session. at [website_path]/vendor/magento/framework/Session/SessionManager.php:175, Magento\\Framework\\Exception\\LocalizedException(code: 0): Area code is not set at [website_path]/vendor/magento/framework/App/State.php:152)"} []
How can I find the problem?
Where can I start?
Thank you
@samuelecarpene do you have any custom console commands? If you do make sure you have set the area code to the appropriate one. Check https://mage2.pro/t/topic/1666/2 out for the list of area codes.
@ferrazzuk this is not related to a console command. I see this error in the exception log (every 5/10 seconds 1 entry) but i'm not able to find where is the problem (maybe if i'll find where is the probelm i'll can solve it). Any idea to where to see or how to identify the origin of the exception?
@samuelecarpene if you use PHPStorm you can set your debugger to stop on SessionException's. If you do have PHPStorm and a debugger setup, go to "Run - View Breakpoints - +" then add a new PHP exception and type the name of the exception then click on the relevant namespace.
@ferrazzuk the error is in the production env (where there insn't xdebug). The problem is that i cannot reproduce the error (as i said i have no idea where the code is generated) so i'm a step before debugging.
Hi @samuelecarpene, not enough information to guess as to me. Too bad there is no full exception stack trace in the log file (can you add such logging on this prod env or there is no access to code?).
I'd do:
php bin/magento -vv
(to check for obvious errors, should display none)
and check your env.php and redis/memcache settings..
maybe even flush cache and redis-cli -p 6380 flushall to boot!
restart varnish/php-fpm/nginx
After searching in log i found that the problem was there because of a third part module. Thank you all.
@samuelecarpene what was the problem?
@ferrazzuk i did not investigate on the problem because it was present only in production. The module is this (https://github.com/magespecialist/m2-MSP_DevTools) if someone experiece the same problem.
I am having this issue as well while upgrading my magento from 2.1 to 2.2.
Apparently, some our custom modules inject their Command classes using Magento\Sales\Api\OrderManagementInterface and because of the DI chain, it ends up instantiating Magento\Payment\Helper\Data which then calls Magento\Framework\Session\SessionManager
This doesn't happen in 2.1.
My fix is to move Magento\Sales\Api\OrderManagementInterface and Magento\Sales\Api\Data\OrderInterface from constructor injection into the execute() function and use ObjectManager. Maybe it's not best practice but at least we can upgrade to 2.2
As @yohanespradono mentioned, this was a problem with the Command classes. When I commented those out in di.xml, compilation succeeded.
To solve the problem, I created the following class:
<?php
namespace Vendor\Module\Helper;
class AreaCode
{
public function __construct(
\Magento\Framework\App\State $state
)
{
$this->state = $state;
$this->setAreaCode();
}
public function getAreaCode()
{
try
{
return $this->state->getAreaCode();
}
catch (\Exception $e)
{
return null;
}
}
public function setAreaCode($code = "frontend")
{
$areaCode = $this->getAreaCode();
if (!$areaCode)
$this->state->setAreaCode($code);
}
}
Including this class in the constructor of the problematic Command classes BEFORE any other classes that might load the SessionManager class, will solve the problem.
Although a bit late but this will still help and the problem still persists.
Please use factories in your command class constructor injection
public function __construct(
YourClassFactory $yourClassFactory,
State $state,
?string $name = null
) {
parent::__construct($name);
$this->yourClassFactory = $yourClassFactory;
}
protected function execute(InputInterface $input, OutputInterface $output): void
{
$this->appState->setAreaCode(Area::AREA_GLOBAL);
$this->yourClass = $this->yourClassFactory->create();
}
Most helpful comment
I am having this issue as well while upgrading my magento from 2.1 to 2.2.
Apparently, some our custom modules inject their Command classes using Magento\Sales\Api\OrderManagementInterface and because of the DI chain, it ends up instantiating Magento\Payment\Helper\Data which then calls Magento\Framework\Session\SessionManager
This doesn't happen in 2.1.
My fix is to move Magento\Sales\Api\OrderManagementInterface and Magento\Sales\Api\Data\OrderInterface from constructor injection into the execute() function and use ObjectManager. Maybe it's not best practice but at least we can upgrade to 2.2