404-Handling statt Exception in Extbase: Catching 1297759968

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?

  1. Der ActionController, den unser JobController erweitert, führt in der processRequest-Methode mapRequestArgumentsToControllerArguments aus.
  2. 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).
  3. Handelt es sich beim $rawValue um eine ID, fühlt sich der PersistentObjectConverter zuständig. Findet er die ID nicht, wirft er eine TargetNotFoundException.
  4. 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;
        }
    }
}

Andere Ideen oder Lösungsvorschläge? Ich freue mich über Anregungen!

Kommentare sind geschlossen.