Magento 2 – Custom No Route Handler

magento2

I have added a custom no route handler using the following code

<?xml version="0.1"?>
<config>
    <type name="Magento\Framework\App\Router\NoRouteHandlerList">
        <arguments>
            <argument name="handlerClassesList" xsi:type="array">
                <item name="hello" xsi:type="array">
                    <item name="class" xsi:type="string">Smartie\HelloRouter\App\Router\NoRouteHandler</item>
                    <item name="sortOrder" xsi:type="string">10</item>
                </item>
            </argument>
        </arguments>
    </type>
</config>

Which is all good it addes the handler and i proved it by

<?php

namespace Smartie\HelloRouter\App\Router;

class NoRouteHandler implements \Magento\Framework\App\Router\NoRouteHandlerInterface
{
    public function process(\Magento\Framework\App\RequestInterface $request)
    {
        die('woop');
    }
}

What i have noticed though is that if i return false in the process function i end up with Front controller reached 100 router match iterations. After looking at the NoRouteHandlerList it seems that by adding my new no route handler it actually replaces all of the no route handlers already added (the default one) and i wondered why?

The following similar code for adding a new router has the effect of appending a new router to the list

<type name="Magento\Framework\App\RouterList">
    <arguments>
        <argument name="routerList" xsi:type="array">
            <item name="custom" xsi:type="array">
                <item name="class" xsi:type="string">Smartie\HelloRouter\Controller\Router</item>
                <item name="disable" xsi:type="boolean">false</item>
                <item name="sortOrder" xsi:type="string">20</item>
            </item>
        </argument>
    </arguments>
</type>

Note: This is magento 2 version 0.74.0-beta16

Best Answer

I ran into this as well. The crux of the issue is covered here in the documentation:

http://devdocs.magento.com/guides/v2.0/extension-dev-guide/depend-inj.html#dep-inj-mod-type-args

When the configuration files for a given scope are merged, array arguments with the same name are merged into a new array. If a new configuration is loaded at a later time, either a more specific scope or through code, then any array definitions in the new configuration will completely replace the previously loaded config instead of being merged.

(emphasis mine)

In my case, I was adding a custom NoRouteHandler through {module}/etc/frontend/di.xml, whereas the core handlers are defined in {module}/etc/di.xml. Since 'frontend' is a more specific scope, my custom handler replaced the core handlers rather than adding to them.

Move your di.xml from whatever config scope you have it in to the etc folder, and all will be well.

See also:

  • app/code/Magento/Backend/etc/di.xml
  • app/code/Magento/Store/etc/di.xml
Related Topic