404-Handling statt Exception in Extbase: Catching 1297759968
Von Thomas Heilmann, veröffentlicht am 08.08.2013
Nehmen wir an, wir zeigen mit einer Extbase-Extension Stellenausschreibungen an. Neben der Listenansicht gibt es eine showAction, der die Ausschreibung übergeben wird. Aus dem Query-String tx_jobs_pi[job]=1 macht der PropertyMapper von Extbase ein Job-Objekt, alles gut soweit. Aber was passiert, wenn die Ausschreibung nicht mehr aktuell ist und deaktiviert wird?
- Der ActionController, den unser JobController erweitert, führt in der processRequest-Methode mapRequestArgumentsToControllerArguments aus.
- Dort wird für jedes Argument die Methode setValue aufgerufen, wo wiederum der PropertyMapper ins Spiel kommt, um aus dem $rawValue das Objekt zu generieren (PropertyMapper->convert).
- Handelt es sich beim $rawValue um eine ID, fühlt sich der PersistentObjectConverter zuständig. Findet er die ID nicht, wirft er eine TargetNotFoundException.
- Diese Exception wird vom PropertyMapper nochmal gefangen und in eine allgemeinere Exception verpackt, mit der der Request dann letztlich endet.
Das Problem: Suchmaschinen löschen die URL u.U. nicht gleich aus dem Index, das Exception-Log von TYPO3 wird unnötig länger – und vor allem wird der Besucher mit einer Fehlermeldung konfrontiert, statt eine ordentliche 404-Seite zu bekommen.
Die Lösung: Man fängt die Exception und löst stattdessen das reguläre TYPO3-404-Handling aus. Dazu muss lediglich im Controller die processRequest-Methode überschrieben werden:
/**
* @param \TYPO3\CMS\Extbase\Mvc\RequestInterface $request
* @param \TYPO3\CMS\Extbase\Mvc\ResponseInterface $response
* @throws \Exception|\TYPO3\CMS\Extbase\Property\Exception
*/
public function processRequest(\TYPO3\CMS\Extbase\Mvc\RequestInterface $request, \TYPO3\CMS\Extbase\Mvc\ResponseInterface $response) {
try {
parent::processRequest($request, $response);
}
catch(\TYPO3\CMS\Extbase\Property\Exception $e) {
if ($e->getPrevious() instanceof \TYPO3\CMS\Extbase\Property\Exception\TargetNotFoundException) {
$GLOBALS['TSFE']->pageNotFoundAndExit('Die gewünschte Stellenausschreibung wurde nicht gefunden.');
} else {
throw $e;
}
}
}