White page or HTTP Error 500 (Internal Server Error)

Not long ago a customer of us had a problem with editing addresses from orders in the Magento admin panel. They noticed for a while that after clicking the edit button by the order it took like 30 seconds before the form to edit the address appeared. But now they only saw a white page. This white page was because of the error handling of the server. Normally you would see a "HTTP Error 500 (Internal Server Error): An unexpected condition was encountered while the server was attempting to fulfill the request" error page.

After looking at the PHP error log we found that the problem had to do with a excessive memory use. The problem reported in the PHP error log was "PHP Fatal error: Allowed memory size of 536870912 bytes exhausted (tried to allocate * bytes) in /*/lib/Varien/*.php on line *". I replaced some parts of the message with stars (*) because the file and the line where the problem appeared was not consistent. After a quick google search I found an article about the same problem and they sad they had the solution for this problem (original article). This last claim was partly true. The located problem and the code they used where correct but the way they used it wasn’t.

They found out that the problem was the way Magento loads the address from an order. In this article I won’t go to deep in explaining what the problem was but it comes down on that Magento loads all the addresses from the database into the code before they select the right address. This means that all the addresses are loaded into the memory and this makes the admin panel extremely slow and with the size of our customers webshop it even broke the whole editing page because there was not enough memory.

The suggested solution to override the follow code:

  1. /**
  2.  * Edit order address form
  3.  */
  4. public function addressAction()
  5. {
  6.     $addressId = $this->getRequest()->getParam('address_id');
  7.     $address = Mage::getModel('sales/order_address')
  8.         ->getCollection()
  9.         ->getItemById($addressId);
  10.     if ($address) {
  11.         Mage::register('order_address', $address);
  12.         $this->loadLayout();
  13.         $this->renderLayout();
  14.     } else {
  15.         $this->_redirect('*/*/');
  16.     }
  17. }

with:

  1. /**
  2.  * Edit order address form
  3.  */
  4. public function addressAction()
  5. {
  6.     $addressId = $this->getRequest()->getParam('address_id');
  7.     //$address = Mage::getModel('sales/order_address')
  8.     //    ->getCollection()
  9.     //    ->getItemById($addressId);
  10.     // bugfix
  11.     $address = Mage::getModel('sales/order_address')->load($addressId);
  12.     if ($address) {
  13.         Mage::register('order_address', $address);
  14.         $this->loadLayout();
  15.         $this->renderLayout();
  16.     } else {
  17.         $this->_redirect('*/*/');
  18.     }
  19. }

And it Worked like a charm. The reason for that was that now only one address was loaded from the database. The only problem was they suggested to override this Magento controller by putting a copy in the local code pool. This doesn't work with controllers because of the way Magento’s autoloading works.

The right way to do this is by creating a new extension and let it override only the address action. I don’t go over the whole process of creating a Magento extension in this article but to override the core controller we use the following code in the config.xml file:

  1. <config>
  2.     <admin>
  3.         <routers>
  4.             <adminhtml>
  5.                 <args>
  6.                     <modules>
  7.                         <alterweb_adressediting before="Mage_Adminhtml">
  8.                             AlterWeb_AddressEditing_Adminhtml
  9.                         </alterweb_adressediting>
  10.                     </modules>
  11.                 </args>
  12.             </adminhtml>
  13.         </routers>
  14.     </admin>
  15. </config>

And create the controller in app/code/community/AlterWeb/AddressEditing/controllers/Adminhtml/Sales/OrderController.php with the following code:

  1. require_once Mage::getModuleDir('controllers', 'Mage_Adminhtml').DS.'Sales'.DS.'OrderController.php';
  2. class AlterWeb_AddressEditing_Adminhtml_Sales_OrderController
  3.     extends Mage_Adminhtml_Sales_OrderController
  4. {
  5.     /**
  6.      * Edit order address form
  7.      */
  8.     public function addressAction()
  9.     {
  10.         $addressId = $this->getRequest()->getParam('address_id');
  11.         $address = Mage::getModel('sales/order_address')->load($addressId);
  12.         if ($address) {
  13.             Mage::register('order_address', $address);
  14.             $this->loadLayout();
  15.             $this->renderLayout();
  16.         } else {
  17.             $this->_redirect('*/*/');
  18.         }
  19.     }
  20. }

That’s it. Now you can fix the problem yourself or download the extension we made. Hope this helps you out.


Download the Magento extension