4

In the process of setting up my site, I have been unable to use category view links of the form:

/catalog/category/view/id/

Similar links to a product view page work just fine. The above leads to the "no-route" CMS page. I tried every category ID in my store, I tried reindexing data, clearing the cache, and disabling the few 3rd party modules I have installed.

Since I'm fairly new to Magento, any general tips on how to go about debugging a problem like this would be greatly appreciated!

  • Do you set action option form, right? – Anthony Jan 25 '13 at 4:56
  • Do SEF rewrites work, e.g. /furniture.html if you had sample data installed? – benmarks Jan 25 '13 at 16:11
  • @benmarks I tried adding rewrites for my categories, but they 404 as well. – jars Jan 25 '13 at 18:27
  • When you said you disabled modules, did you disable them in app/etc/modules (correct way) or did you just disable the html output in advanced section of configuration? The latter wont help too much for this. – Bryan Ruiz Jan 26 '13 at 6:36
4

If this error were occurring for product pages, I would be inclined to look into a problem with URL rewrites and/or an issue with catalog module route configuration i.e. the contents of the frontend/routers/catalog xpath in config. That your products are working tells me that there is nothing universally broken with either of these two.

Errors, can you see them?

Depending on the error, Magento route-to-controller matching may not work for the standard router, in which case the 404 page will be displayed via the default router. I would start by ruling out core code changes and custom modules. Enable error reporting for PHP and set Magento developer mode to true; see index.php and edit directly, or set the necessary params prior to PHP (e.g. in .htaccess if you are using Apache). Check error logs in var/log/.

Core Changes

If possible, use a stock copy of your version of Magento, point it at the database, and see if the problem remains. If so, it's a data issue, which may come from code, but at least you'll have an indication of where to look.

Custom code

Back in the "regular" instance, rule out local-codePool modules by setting the disable_local_modules flag in app/etc/local.xml to true and test the effect (assuming that the declaration files in app/etc/modules/ follow convention and don't do anything besides declaring the module).

Community-codePool modules cannot be disabled this way, so it would be necessary to rename the community codePool temporarily to effectively disable them (again, assuming that the declaration files in app/etc/modules/ follow convention and don't do anything besides declaring the module). Test the effect and see what happens.

Magento routing normally works, so by iterating through the code and config which is used when routing, it's possible to winnow away culprits and help reveal the problem.

11

There's multiple reasons the category view page may return a 404. I'll get to the specific code in a minute, but high level you'll want to

  1. Make sure your URL includes a numeric ID paramater

  2. Make sure your category is set to "active" in the backend

  3. Make sure your category is the member of a root category list in the category management page

For me the best way to debug these problems is to get down into the code. The category URL routes to the following controller class

#File: app/code/core/Mage/Catalog/controllers/CategoryController.php

Specifically, the following viewAction method

#File: app/code/core/Mage/Catalog/controllers/CategoryController.php
public function viewAction()
{
    if ($category = $this->_initCatagory()) {
        //...code snipped for brevity...
    }
    elseif (!$this->getResponse()->isRedirect()) {
        $this->_forward('noRoute');
    }
}    

For starters, I'd temporarily add some debugging code to make sure your controller is routing to the correct place

public function viewAction()
{
    var_dump(__METHOD__);
    exit;
    //...
}

If you don't see the method name dumped to the browser with the above code in place, that means there's a rewrite or override conflict with another module.

If that checks out, as you can see from the method definition, if the _initCategoty method returns false, the category page will go to the no route 404 page. Jumping up to _initCategory, you can see there's three reasons why this might happen.

First

#File: app/code/core/Mage/Catalog/controllers/CategoryController.php
protected function _initCatagory()
{
    //...    
    Mage::dispatchEvent('catalog_controller_category_init_before', array('controller_action' => $this));
    $categoryId = (int) $this->getRequest()->getParam('id', false);
    if (!$categoryId) {
        return false;
    }
    //...
}

If there's no id paramater in the URL, the method will return false and you'll get a 404.

Next, Magento loads a category and runs the following

#File: app/code/core/Mage/Catalog/controllers/CategoryController.php
protected function _initCatagory()
{
    //...    
    if (!Mage::helper('catalog/category')->canShow($category)) {
        return false;
    }
    //...
}

There's a set of rules in canShow Magento runs the category through. If those fail, you get a 404 page. (we'll get to those rules in a second)

Finally, Magento dispatches a catalog_controller_category_init_after event

#File: app/code/core/Mage/Catalog/controllers/CategoryController.php
try {
    Mage::dispatchEvent(
        'catalog_controller_category_init_after',
        array(
            'category' => $category,
            'controller_action' => $this
        )
    );
} catch (Mage_Core_Exception $e) {
    Mage::logException($e);
    return false;
}

If any event observers throw an exception, Magento will log the error message and display a 404 page.

I'd recommend you add temporary debugging code above each return false

var_dump(__METHOD__ . '::' . __LINE__);
exit;
return false;

This will tell you which conditional is failing. For the exception, an extra

var_dump($e->getMessage());

is a good idea.

If it's canShow that's failing, you can find those tests in

#File: app/code/core/Mage/Catalog/Helper/Category.php
public function canShow($category)
{
    if (is_int($category)) {
        $category = Mage::getModel('catalog/category')->load($category);
    }

    if (!$category->getId()) {
        return false;
    }

    if (!$category->getIsActive()) {
        return false;
    }
    if (!$category->isInRootCategoryList()) {
        return false;
    }

    return true;
}

As you can see, this is where the checks for an active category, or ensuring the category is in the root list live. Similar debug code here should let you figure out what the exact problem is.

  • thank you very much for this helpful post, with your advice i was able to find the exact issue (in the canShow() method.) as for why that part is failing, I guess thats a few more hours of research :) – jars Jan 29 '13 at 0:37
  • 1
    in the possible chance that this helps someone else, the canShow() method calls isInRootCategoryList on the category, which failed for me, because the root category of my store was erroneously set to an empty one, rather than the one with all my products in it. Dumb error, but rather difficult for me to find. – jars Jan 29 '13 at 1:17
  • @JamesA Don't feel bad, I've seen that trip up a bunch of people. – Alan Storm Jan 29 '13 at 1:38
2

Generally, the best way in Magento to debug is to dig in the code and have a certain amount of patience :). First off all you have to figure out in what file the problem is generated (Or what table). Things like a debug toolbar and template path hints can easily point you in the right direction. Then you can move on to debugging in detail. I usually put a Mage::log in the functions to see what function is generated then I go deeper into the problem. If there are any table / query related problems you could always turn on $_debug and query logging (the latter is usually available in a debug toolbar). For debugging an indexer I advice you to trigger it from command line because it returns the errors more propperly. The rest is just digging, digging and digging but after a while it gets faster and faster.

The only other advice i can give you is try to solve as much as problems yourself, here in Belgium we have a simple saying called 'You learn while doing'.

  • Thank you very much for your advice! If there is not a specific answer to my problem then I will mark this as the answer. – jars Jan 25 '13 at 18:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.