В общем и целом, проверка (defined('ERROR_404') && ERROR_404 == 'Y') не позволяет отловить возникновение 404 ошибки в обработчике. Я писал по этому поводу в техподдержку, они передали мой тикет в разработку. Это было в октябре. Пока они слоупочат, вы можете перенести проблемный компонент в свое пространство имен, найти, где в нем вызывается CHTTP::SetStatus и добавить после него нужную строку:
CHTTP::SetStatus('404 Not found');
defined('ERROR_404') or define('ERROR_404', 'Y');
Либо, вы можете сравнить $arResult, который передается в шаблон при заходе на /catalog/ и при заходе на /catalog/abrakadabra, и найти такое условие, которое позволило бы определять, что возникла ошибка. По-моему, там есть что-то с TEMPLATE_NAME. Тогда добавите в index.php в шаблоне примерно следующее:
if ($arResult['TEMPLATE_NAME'] !== 'index.php')
{
defined('ERROR_404') or define('ERROR_404', 'Y');
}
Либо, если вы не хотите этого делать, вы можете модифицировать сам метод CHTTP::SetStatus, как-то так:
class CHTTP
{
public static function SetStatus($status)
{
...
if ($status === '404 Not found')
defined('ERROR_404') or define('ERROR_404', 'Y');
}
}
Но это не приветствуется битриксом, и будет слетать при каждом обновлении.