Для начала отключаем режим показа 404-й страницы в настройках компонента каталога.
Далее, открываем файл section.php каталога и тут настраиваем свой код определения того, какую страницу показывать - страницу товара или страницу раздела - проверяем по базе данных, если есть товар с заданным символьным кодом - показываем карточку товара. Если товара нет, но есть раздел с таким символьным кодом - показываем его. Если же ни товара, ни раздела с заданным символьным кодом нет - нужно показать 404-ю страницу. Для этого можно воспользоваться следующим кодом:
if (!defined("ERROR_404"))
define("ERROR_404", "Y");
\CHTTP::setStatus("404 Not Found");
if ($APPLICATION->RestartWorkarea())
{
require(\Bitrix\Main\Application::getDocumentRoot() . "/404.php");
die();
}
В результате пользователю будет показана 404-я страница. Адрес при этом не изменится.
2019-02-28. Решение, используемое в ядре системных компонентов:
Bitrix\Iblock\Component\Tools::process404(
'Не найден', //Сообщение
true, // Нужно ли определять 404-ю константу
true, // Устанавливать ли статус
true, // Показывать ли 404-ю страницу
false // Ссылка на отличную от стандартной 404-ю
);
Типовой каркас 404-й страницы:
<?
include_once($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/urlrewrite.php');
CHTTP::SetStatus("404 Not Found");
@define("ERROR_404", "Y");
require($_SERVER["DOCUMENT_ROOT"] . "/bitrix/header.php");
$APPLICATION->SetTitle("Страница не найдена");
$APPLICATION->SetPageProperty("keywords", "Страница не найдена");
$APPLICATION->SetPageProperty("description", "Страница не найдена");
?>
<div class="container-error-page">
<div class="error-page-big-text">
404
</div>
<div class="col col-12 ta-center">
<?$APPLICATION->IncludeComponent(
"bitrix:search.form",
"bottom",
array(
"COMPONENT_TEMPLATE" => "bottom",
"PAGE" => SITE_DIR."search/index.php"
),
false
);?>
</div>
<p>
<a href="/">Главная страница</a>
</p>
<p>
<a href="search/map.php">Карта сайта</a>
</p>
</div>
<? require($_SERVER["DOCUMENT_ROOT"]."/bitrix/footer.php"); ?> 
