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
- In
Redaction::article(), when no article matches, throw an exception instead of returningnull:throw new Exception("No article has the slug “{$slug}”.");, withuse Exception;below thenamespace(see the Reminder). The method now always returns anArticle: its return type loses its?. - In the article handler, remove the
nulltest: it is no longer needed. - In the front controller, wrap the call to the handler in a
try, and catch the exception withcatch (Exception)to showPage::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.