I'm looking after a Magento shop with 400-500 visitors and 40-50 orders per day.
Recently system was upgraded from Magento EE 1.14.2.4 to Magento EE 1.14.3.2 and I noticed some strange exceptions in logs:
exception 'Mage_Core_Model_Session_Exception' in
/var/www/.../app/code/core/Mage/Core/Model/Session/Abstract/Varien.php:418
I was chasing that exception and I do know that it is being fired because the following session validation code fails to validate the session:
class Mage_Core_Model_Session_Abstract_Varien extends Varien_Object
{
// ...
protected function _validate()
{
// ...
if ($this->useValidateSessionExpire()
&& isset($sessionData[self::VALIDATOR_SESSION_EXPIRE_TIMESTAMP])
&& $sessionData[self::VALIDATOR_SESSION_EXPIRE_TIMESTAMP] < time() ) {
This if-block was added to the file with latest release from Magento. And this is a braking change apparently, see more details below.
The exception is happening quite often, like a dozen times per day. but I'm not able to recreate conditions which lead to the exception, unless I literally put true in the condition above. The
exceptions most often occurs on product detail pages and on the last step of one page checkout. The shop is a b2b shop, the user must be logged in to see product page or to be able to checkout, means user is redirected to login pages when session is invalidated/expired. At the moment it is more important for me to fix this problem during checkout.
What happens from user perspective:
User fills the cart, proceeds to checkout and reaches last step, then he/she hits the "submit the order" button and nothing happens. Behind the scenes Magento's JS performs an AJAX request and JS expects to receive JSON back, but if this error happens the HTML of login page is returned, which can not be parsed by JavaScript and it just does nothing. That is super confusing for users.
Well, that is not complete user scenario, we contacted users and they told us that they waited for few days between filling the cart and submitting the order, what that exactly means is hard to figure out, because people simply don't remember that.
PHP session lifetime – 350000 (~4 days in seconds)
Cookie lifetime – 345600 (4 days)
Here is the actual question:
how can I find out what sort of user behavior lead to the exception?
UPDATE
So far I know that exception happens in following classes according to the request made, to me that means nothing unfortunately.
/catalogsearch/result/?q=… Mage_Core_Model_Session
/checkout/cart/ Mage_Core_Model_Session
/checkout/onepage/saveOrder/… Mage_Rss_Model_Session
/customer/account/loginPost/ Mage_Core_Model_Session
/customer/account/loginPost/ Mage_Reports_Model_Session
/customer/account/logout/ Mage_Reports_Model_Session
/catalog/product/view/… Mage_Reports_Model_Session
/catalog/product/view/… Mage_Tag_Model_Session
UPDATE 2: sessions are stored in files and cleaned up by PHP session garbage collector, whether this is a good choice or not is out of the scope of this question.
Best Answer
After some advanced debugging, session tracing and thinking about all that magic I was able to reproduce the problem and understand the reason for it. I prepared a little timing illustration, you can see it below.
/sales/order/save/...
request)Here is how to reproduce:
Reason:
There are certain sessions which are only instantiated on given requests, e.g.
Mage_Rss_Model_Session
is only instantiated during the actual checkout and not while browsing through catalog. At the same time session expiry timestamp is only set when session was instantiated. That means that if there was enough time between two checkouts and the session was not killed meanwhile (because user logged out or cookie expired) the new Magento code will consider that session as not passing validation and will throw an exception, which sounds somehow strange to me.How to fix:
Well, I have few options:
How did I figure it out:
I started with adding the following to the original code of
Mage_Core_Model_Session_Abstract_Varien
it gave me a good insight about affected classes and their correlation and how much session were expired. But that was not explaining why it happens and which user actions lead to the problem.
Then I started thinking on how can I trace all changes to session data and came across this question https://superuser.com/questions/368231/automatic-versioning-upon-file-change-modify-create-delete I decided to give a try to
git
andincron
combination, but after I implemented it and tested in sandbox, I realized that I will run out of disk space really fast in production.I decided to build a small PHP script which will decode session data and write logs for each sesssion. This script was called by
incron
and here is the corresponding
incrontab
entrysample output
P.S.:
Current versions of both
are not able to handle the exception above during the AJAX request. They display literally nothing to the user, while user effectively gets logged out!
P.P.S.:
apparently Magento CE 1.9.3.x versions are also affected, see https://github.com/OpenMage/magento-mirror/blame/magento-1.9/app/code/core/Mage/Core/Model/Session/Abstract/Varien.php
P.P.P.S.:
When I said "Remove this code meanwhile." I meant excluding the following block
you can do that with so many ways, including:
$this->useValidateSessionExpire()
return true