Pergunta

We recently noticed that SOMETIMES we get 404 page when trying to enter some product. And it happens one in 100 times or so. We don't even know where to start to debug this problem. Because system.log and exception.log doesn't show anything. Anyone have any ideas how to even start to debug this? Please help!

Foi útil?

Solução

This looks to be a new feature of 1.9.3.1 :)

The issue is being caused at the bottom of: Mage_Core_Model_Session_Abstract_Varien::_validate() - app\code\core\Mage\Core\Model\Session\Abstract\Varien.php

if (
    $this->useValidateSessionExpire()
    && isset($sessionData[self::VALIDATOR_SESSION_EXPIRE_TIMESTAMP])
    && $sessionData[self::VALIDATOR_SESSION_EXPIRE_TIMESTAMP] < time() ) {
    return false;
} else {
    $this->_data[self::VALIDATOR_KEY][self::VALIDATOR_SESSION_EXPIRE_TIMESTAMP]
        = $validatorData[self::VALIDATOR_SESSION_EXPIRE_TIMESTAMP];
}

This is basically checking whether the session data has expired by looking at the self::VALIDATOR_SESSION_EXPIRE_TIMESTAMP timestamp, and is done for all session models Magento loads when rendering the page. Put Mage::log('VALIDATING SESSION: '.get_class($this)) in the function and you'll see the sessions that are validated in your system.log.

The problem is that Magento loads additional sessions when viewing a product page compared to, for instance, viewing the home page. Therefore the expires timestamps can vary between different session models.

If one of these session is deemed to be expired and invalid then the cookie is deleted - Mage_Core_Model_Session_Abstract_Varien::validate(), and all sessions are invalidated. This causes a 404 when it happens and you are trying to view a product page.

You can see this in action by doing the folowing on a dev system:

  • IN ADMIN
    • drop the cookie lifetime down to 30 seconds (system/configuration/general/web/Session Cookie Management)
  • ON FRONTEND
    • Open a product page in a new tab
    • Open the login page in another tab
    • login and wait 30> seconds refreshing the page occasionaly to update the session cookie expiry so your session is kept alive
    • After 30 seconds go to product page tab and refresh => you should get the 404 you've been seeing.

The solution we've used to solve this is to only validate the $sessionData[self::VALIDATOR_SESSION_EXPIRE_TIMESTAMP] for the main Mage_Core_Model_Session class:

if (
// MODIFIED_CORE - added
    get_class($this) == 'Mage_Core_Model_Session' &&
// MODIFIED_CORE - end - added
    $this->useValidateSessionExpire()
    && isset($sessionData[self::VALIDATOR_SESSION_EXPIRE_TIMESTAMP])
    && $sessionData[self::VALIDATOR_SESSION_EXPIRE_TIMESTAMP] < time() ) {
    return false;
} else {
    $this->_data[self::VALIDATOR_KEY][self::VALIDATOR_SESSION_EXPIRE_TIMESTAMP]
        = $validatorData[self::VALIDATOR_SESSION_EXPIRE_TIMESTAMP];
}

I'm assuming that Magento put this in to stop someone from setting the clock back in time on their computer so that an expired cookie session id can be used. If this was to happen then the above modification still catches this.

SIDE NOTE: There is another session issue similar to this that causes logged in customers to be logged out when they go to checkout:

  • drop the cookie lifetime down to 30 seconds (system/configuration/general/web/Session Cookie Management)
  • log in
  • navigate around the "My Account" area for 30 seconds - after the 30 seconds the session will be destroyed you'll be logged out.

See here for more info: https://magento.com/tech-resources/bug-tracking/issue/index/id/1534/

Outras dicas

Observe following the event in your custom module or make temporary if don't have.

catalog_product_save_before = runs before saving product

catalog_product_save_after = runs after saving product

controller_action_predispatch = runs before action

controller_action_postdispatch = runs after action

Replace SampleNamespace_XyzModule with your namespaces and modules.

class SampleNamespace_XyzModule_Model_Observer
{     
    public function catalog_product_save_before($observer)
    {
        $product = $observer->getProduct();        
        Mage::log($product->getData(), null, 'cp_save_before.log');            

    }

    public function catalog_product_save_after($observer)
    {
        $product = $observer->getProduct();        
        Mage::log($product->getData(), null, 'cp_save_after.log');

    }

    public function hookToControllerActionPreDispatch($observer)
    {
        $actionName = $observer->getEvent()->getControllerAction()->getFullActionName();
        Mage::log($actionName, null, 'cp_save_preDispatch.log');

    }

    public function hookToControllerActionPostDispatch($observer)
    {
        $actionName = $observer->getEvent()->getControllerAction()->getFullActionName();
        Mage::log($actionName, null, 'cp_save_postDispatch.log');

    }

}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a magento.stackexchange
scroll top