-
-
Notifications
You must be signed in to change notification settings - Fork 449
Throw exception to prevent infinite loop caused by third party code. #1244
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Integrate solution from @convenient for issues described in the pull request on magento2 repository magento/magento2#18678 In our case the problem occurred with the MSP_CashOnDelivery extension, after a long debugging session we were able to identify and reproduce the problem and trace the MSP_CashOnDelivery extension causes an infinite loop and timeout of the request if trigger_recollect column is set to 1 in the sales_flat_quote table It would be useful to integrate this solution from @convenient that throw new Exception to quickly identify any third party extensions affected by the same problem But can there be copyright problems in this case? and in the future how can we do for porting a bug fixed on magento 2 to magento-lts?
Licensing aside this patch pretty much matches my initial version. I applied this to a M1 client a few years back when debugging infinite looping quotes on a production site, that formed the basis of my M2 pull request. |
after further hours of debugging and testing I think the definitive solution to the problem is this: Related Pull RequestsFix
Descriptionif a customer quote is marked with the "trigger_recollect" flag More detail descriptionif "trigger_recollect" is marked, after loading the quote Mage_Sales_Model_Quote the Mage_Sales_Model_Quote::collectTotals() method is called from Mage_Sales_Model_Quote::_afterLoad() which calls the "collect" method for each model of 3rd party payment / shipping method.
if one of these $models attempts to reloading the quote Mage_Sales_Model_Quote::_afterload() method is recalled and Mage_Sales_Model_Quote::recollectTotals() restarts causing the loop Reproduction of the scenario call stack:Mage_Sales_Model_Quote::load()
here if some 3rd party payment/shipping method in its collect() method reload the quote before collectTotals ended and "trigger_recollect" is marked starts the loop in our case MSP_CashOnDelivery_Helper_Data::getQuote() call Mage_Checkout_Model_Session->getQuote() that attempts to loading the quote into the session
reloading the quote before collectTotals()
Our complete backtrace of the loop:
|
I must advise against this pull request as it causes problems with many widely used modules such as MSP_CashOnDelivery and others. We have definitely solved the issues thanks to this change #1248 |
@empiricompany surely it only causes an exception when an infinite loop is about to occur? |
@convenient yes but many widely used extensions have this problem that occurs when there are products in the cart affected by unsynchronized catalog rules, because the extension prevents the setting of the trigger_recollect flag causing the loop. |
@empiricompany I agree there will be a lot of modules out there with this problem that could be affected by this PR. But in the request flow where this logic exception fires isn't that particular request already broken because it will be in an infinite loop. This PR was never meant to fix anything, just to prevent requests gobbling up all the system resources and to give a useful stack trace. The infinite loop requests may be currently being killed by Max execution time limits for example, but they are still broken requests. This PR just breaks them earlier with a clear stack trace. I can't see how this PR would make anything worse, the purpose of throwing a logic exception is to tell you you have a but somewhere else in your code. |
@convenient in our experience with some catalog rules that affects the cart and the MSP_CashOnDelivery extension this exception was useful for us to identify the problem but we had to remove it otherwise it was raised because it seems to me that it must do at least "2 loop cycles" (or more depends on how many extension causing the loop) before stopping thanks to the setting of the flag "trigger_recollect". |
@empiricompany Ahhh interesting I have never actually come across a scenario where multiple loops are needed, it's always been one loop in my experiences. Having a counter could also work I suppose then and there is precedent within the magento core like in the router magento-lts/app/code/core/Mage/Core/Controller/Varien/Front.php Lines 188 to 200 in 8ca6fd9
|
@convenient I can confirm that even after the modification suggested by @colinmollenhour in the PR #1248 and with the simple flag isLoading any problematic extensions such as MSP_CashOnDelivery cannot get out of the loop. We have tested it in production.
|
@empiricompany that seems like a great amendment |
Thank you for your contributions and the very interesting discussion here. As we have merged #1248, it seems we do not need to merge this one for now. Especially as @empiricompany is currently advising against merging it. Still, if someone else may run into similar problems, we may reopen it and potentially merge it into a later version which is allowed to be less backwards compatible. |
@Flyingmana all makes sense. But to be clear this isn't about collecting the totals more than once, but collecting the totals more than once without the quote having being assigned to the session singleton. A very subtle difference. |
Integrate solution from @convenient for issues described in the pull request on magento2 repository
magento/magento2#18678
In our case the problem occurred with the MSP_CashOnDelivery extension, after a long debugging session we were able to identify and reproduce the problem and trace the MSP_CashOnDelivery extension causes an infinite loop and timeout of the request if trigger_recollect column is set to 1 in the sales_flat_quote table
It would be useful to integrate this solution from @convenient that throw new Exception to quickly identify any third party extensions affected by the same problem
But can there be copyright problems in this case? and in the future how can we do for porting a bug fixed on magento 2 to magento-lts?
Description (*)
Related Pull Requests
Fixed Issues (if relevant)
Manual testing scenarios (*)
Questions or comments
Contribution checklist (*)