404 page not shown if catalog not exist
Forum rules
Always add your TYPO3, Aimeos and PHP version as well as your environment (Linux/Mac/Win)
Spam and unrelated posts will be removed immediately!
Always add your TYPO3, Aimeos and PHP version as well as your environment (Linux/Mac/Win)
Spam and unrelated posts will be removed immediately!
404 page not shown if catalog not exist
Hi Aimeos-Team,
if we call a catalog-URL that does not exist, instead of showing 404 page, the exception is thrown (catalog with id 123 does not exist)
For product (detail-page) the 404 page is shown.
catalog id 123 not exists:
/shop/123/category-not-exist : exception, should 404
/detail/123/category-not-exist/product-name: exception, should 404
/detail/1234/category-exist/product-name-not-exist: 404, its ok
The TYPO3 error handling is "Show content from pid".
The route enhancer block from siteconfig:
We have
- Multi-Site
- Aimeos 2024
- TYPO3 v12.4.36
And is it possible to can do the routing without the catalog id? The detail/product url works fine without the product id.
Thank you for your support!
if we call a catalog-URL that does not exist, instead of showing 404 page, the exception is thrown (catalog with id 123 does not exist)
For product (detail-page) the 404 page is shown.
catalog id 123 not exists:
/shop/123/category-not-exist : exception, should 404
/detail/123/category-not-exist/product-name: exception, should 404
/detail/1234/category-exist/product-name-not-exist: 404, its ok
The TYPO3 error handling is "Show content from pid".
The route enhancer block from siteconfig:
Code: Select all
routeEnhancers:
Aimeos:
type: Extbase
namespace: ai
defaultController: 'Catalog::list'
# only on aimeos pages
limitToPages:
- 1323
- 1326
- 1331
- 1328
- 1365
- 2022
- 2025
- 1344
- 1340
- 1343
- 1337
routes:
-
routePath: '/pin/{pin_action}/{pin_id}/{d_name}'
_controller: 'Catalog::detail'
-
routePath: '/history/{his_action}/{his_id}'
_controller: 'Account::history'
-
routePath: '/watch/{wat_action}/{wat_id}'
_controller: 'Account::watch'
-
routePath: '/watch/{wat_action}'
_controller: 'Account::watch'
-
routePath: '/fav/{fav_action}/{fav_id}'
_controller: 'Account::favorite'
-
routePath: '/fav/{fav_action}'
_controller: 'Account::favorite'
-
routePath: '/b/{b_action}'
_controller: 'Basket::index'
-
routePath: '/co/{c_step}'
_controller: 'Checkout::index'
-
routePath: '/p/{d_name}/{d_prodid}/{d_pos}'
_controller: 'Catalog::detail'
-
routePath: '/lt/{l_type}'
_controller: 'Catalog::list'
-
routePath: '/lp/{l_page}'
_controller: 'Catalog::list'
-
routePath: '/ls/{f_sort}/{l_page}'
_controller: 'Catalog::list'
-
routePath: '/l/{f_sort}'
_controller: 'Catalog::list'
-
routePath: '/{f_catid}/{f_name}'
_controller: 'Catalog::list'
-
routePath: '/{f_catid}/{f_name}/{d_name}'
_controller: 'Catalog::detail'
requirements:
pin_id: \d+
his_id: \d+
wat_id: \d+
fav_id: \d+
d_prodid: \d+
d_pos: '\d*'
l_page: \d+
f_catid: \d+
d_name: '[^/]+'
f_name: '[^/]+'
f_sort: '[A-Za-z0-9_-]*'
l_type: '[A-Za-z0-9_-]+'
b_action: '[A-Za-z0-9_-]*'
c_step: '[A-Za-z0-9_-]*'
defaults:
b_action: ''
c_step: ''
f_name: c
f_sort: ''
d_pos: '
- Multi-Site
- Aimeos 2024
- TYPO3 v12.4.36
And is it possible to can do the routing without the catalog id? The detail/product url works fine without the product id.
Thank you for your support!
Thanks a lot!
Re: 404 page not shown if catalog not exist
Hi,
I am using a Middleware and a custom page not found Handler for such cases:
Middleware:
Middleware registration:
Handler:
Here are the docs for Middlewares and custom error handlers in case you don't know how to configure it:
https://docs.typo3.org/m/typo3/referenc ... wares.html
https://docs.typo3.org/m/typo3/referenc ... Index.html
I am using a Middleware and a custom page not found Handler for such cases:
Middleware:
Code: Select all
<?php
namespace Your\Ext\Middleware;
use Your\Ext\Error\PageNotFoundHandler;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Throwable;
use TYPO3\CMS\Core\Utility\GeneralUtility;
class NotFoundToErrorHandlerMiddleware implements MiddlewareInterface
{
/**
* @throws Throwable
*/
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
try {
$response = $handler->handle($request);
} catch (Throwable $e) {
// Convert application exceptions (e.g., Aimeos errors) into your custom 404 page
try {
/** @var PageNotFoundHandler $handlerService */
$handlerService = GeneralUtility::makeInstance(PageNotFoundHandler::class);
return $handlerService->handlePageError($request, 'Application threw exception: ' . $e->getMessage());
} catch (Throwable) {
// As a last resort, rethrow to keep default TYPO3 exception handling
throw $e;
}
}
// Probe header to verify middleware runs on successful requests too
$response = $response->withHeader('X-NotFound-Middleware', 'on');
// Turn plugin-level 404 errors into your custom 404 page
if ($response->getStatusCode() === 404 && $this->isHtml($response)) {
try {
/** @var PageNotFoundHandler $handlerService */
$handlerService = GeneralUtility::makeInstance(PageNotFoundHandler::class);
return $handlerService->handlePageError($request, 'Application returned 404');
} catch (Throwable) {
return $response;
}
}
return $response;
}
private function isHtml(ResponseInterface $response): bool
{
$type = $response->getHeaderLine('Content-Type');
return $type === '' || str_starts_with($type, 'text/html');
}
}
Code: Select all
return [
'frontend' => [
'your/ext/notfound-to-error' => [
'target' => NotFoundToErrorHandlerMiddleware::class,
'after' => [
'typo3/cms-frontend/tsfe',
],
'before' => [
'typo3/cms-frontend/content-length-headers',
'typo3/cms-frontend/response-propagation',
],
],
];
Code: Select all
<?php
namespace Your\Ext\Error;
use LogicException;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Core\Error\PageErrorHandler\PageErrorHandlerInterface;
use TYPO3\CMS\Core\Http\HtmlResponse;
use TYPO3\CMS\Core\Http\RedirectResponse;
use TYPO3\CMS\Core\Http\RequestFactory;
use TYPO3\CMS\Core\Http\Uri;
use TYPO3\CMS\Core\Site\Entity\Site;
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
use TYPO3\CMS\Core\Utility\GeneralUtility;
class PageNotFoundHandler implements PageErrorHandlerInterface
{
/**
* @var int
*/
protected int $pageNotFoundUid = 1;
/**
* @var ServerRequestInterface
*/
protected ?ServerRequestInterface $request = null;
public function handlePageError(
ServerRequestInterface $request,
string $message,
array $reasons = []
): ResponseInterface
{
$this->request = $request;
return new HtmlResponse($this->getPageNotFoundContent(), 404);
}
/**
* @return string
*/
protected function getPageNotFoundContent(): string
{
$url = $this->getPageNotFoundUrl();
$requestFactory = GeneralUtility::makeInstance(RequestFactory::class);
/** @var ResponseInterface $response */
$response = $requestFactory->request($url, 'GET');
if (($response->getStatusCode() === 200) &&
str_starts_with($response->getHeaderLine('Content-Type'), 'text/html')) {
return $response->getBody()->getContents();
}
throw new LogicException('Could not read content of ' . $url, 1594134183);
}
/**
* @return string
*/
protected function getPageNotFoundUrl(): string
{
/** @var Site $site */
$site = $this->request->getAttribute('site');
/** @var Uri $uri */
$uri = $site->getRouter()->generateUri($this->pageNotFoundUid, ['_language' => $this->getLanguageIdentifier()]);
return $uri->__toString();
}
/**
* @return int
*/
protected function getLanguageIdentifier(): int
{
/** @var SiteLanguage $language */
$language = $this->request->getAttribute('language');
return $language->getLanguageId();
}
}
https://docs.typo3.org/m/typo3/referenc ... wares.html
https://docs.typo3.org/m/typo3/referenc ... Index.html