The missing article

Exercise 8 of 9 in chapter 5 · 150 XP · 3 objectives checked by tests

Topics covered: Exceptionthrowtrycatch

Odette's nephew is preparing a “Gaston's articles” page, and he forgot to test for the null returned by Redaction::article(). The result: Call to a member function versHtmlComplet() on null, an error that shows up far from its cause and doesn't say what is missing. Will every new call to Redaction::article() have to remember the null? No: when the article does not exist, Redaction::article() will throw an exception, and the front controller will catch it, once and for all.

Your mission

  1. In Redaction::article(), when no article matches, throw an exception instead of returning null: throw new Exception("No article has the slug “{$slug}”.");, with use Exception; below the namespace (see the Reminder). The method now always returns an Article: its return type loses its ?.
  2. In the article handler, remove the null test: it is no longer needed.
  3. In the front controller, wrap the call to the handler in a try, and catch the exception with catch (Exception) to show Page::introuvable().

The braces in {$slug} tell PHP where the variable name ends. Without them, PHP would read the closing quote ” as part of the name.

Reminder

An exception is an object that signals a problem. throw throws it: the function stops dead, then the one that called it, and so on, up to a try { … } catch (Exception $erreur) { … } that catches it. If nobody catches it, the page crashes with its message. You have already met one of its cousins: Rubrique::from('sport') throws a ValueError. It is thrown and caught with the same try/catch, but with catch (ValueError), because it is an Error, not an Exception.

Inside the catch, $erreur->getMessage() gives the exception's message. When you don't need the variable, you can leave it out: catch (Exception).

Exception is a class provided by PHP, stored at the root, with no namespace. In public/index.php, which has no namespace, you write it as is. In Redaction, which lives in Gazette\Contenu, you have to import it with use Exception;, otherwise PHP looks for a class called Gazette\Contenu\Exception.