web-dev-qa-db-fra.com

Bonnes pratiques: Utilisation de @throws dans php-doc et comment le gérer

Disons que j'ai une classe avec une méthode comme celle-ci:

/*
 *
 * Loads the user from username.
 *
 * @param string $username The username
 *
 * @return UserInterface
 *
 * @throws userNotFoundException if the user is not found
 */
public function getUser($username)
{
    // someFunction return an UserInterface class if found, or null if not.
    $user = someFunction('SELECT ....', $username);
    if ($user === null) {
        throw new userNotFoundException();
    }

    return $user
}

Maintenant, supposons que someFunction puisse lancer une InvalidArgumentException/RuntimeException/PDOException pour des raisons XYZ. Que devrais-je faire? Et quoi non?

Numéro 1

Ajoutez toutes les exceptions possibles qui pourraient générer someFunction dans php-docs.

/*
 *
 * Loads the user from username.
 *
 * @param string $username The username
 *
 * @return UserInterface
 *
 * @throws userNotFoundException if the user is not found
 * @throws InvalidArgumentException
 * @throws ...
 */

Numéro 2

Ajoutez un bloc try-catch pour vous assurer que la méthode lève des exceptions UNIQUEMENT documentées

/*
 *
 * Loads the user from username.
 *
 * @param string $username The username
 *
 * @return UserInterface
 *
 * @throws userNotFoundException if the user is not found
 * @throws RuntimeException 
 */
public function getUser($username)
{
    try {
        $user = someFunction('SELECT ....', $username);
    } catch (Exception $e) {
        throw new RuntimeException();
    }

    if ($user === null) {
        throw new userNotFoundException();
    }

    return $user
}

Numéro 3

Ne fais rien.

24
Federkun

Personnellement, je considérerais de traiter @throws de la même manière que les exceptions vérifiées de Java.

La façon dont cela fonctionne en Java est que, fondamentalement, les exceptions héritées de RuntimeException peuvent être levées et ne doivent pas être gérées. Tous les autres types d'exceptions doivent avoir un bloc try-catch pour les gérer. Ce code de traitement doit être dans l'appelant.

Fondamentalement dans PHP un peu comme ceci:

Quand une méthode a une annotation @throws, vous devez ajouter du code pour gérer ses exceptions. 

Toute exception non mentionnée est facultative dans le code d'appel.


Maintenant, je ne suis pas à 100% suivre ce principe moi-même. Toute la question des exceptions de gestion est à la hauteur de la préférence du programmeur, mais ce ne sont que quelques réflexions sur la façon dont je pense que cela pourrait être géré de manière raisonnable.

11
Jani Hartikainen

En ce qui concerne la documentation, si une fonction explicitement lève une exception, elle doit être incluse dans la documentation de la fonction. Ainsi, pour chaque instruction throw, il devrait y avoir un @throws correspondant dans la documentation PHP.

En ce qui concerne la gestion, si certaines opérations doivent être exécutées lors de la levée de l'exception, saisissez-la. Sinon, laissez-le bouillonner - à condition qu'il y ait une instruction catch qui le gérera plus tard.

Mettre à jour:

Quelques années plus tard, j'ai changé d'avis pour ne laisser qu'une exception "bouger" sans modification, à condition que cette exception soit encore pertinente pour le niveau d'abstraction du module. Des stratégies de capture et de remise à l'eau doivent être utilisées pour rendre l'exception plus significative. Cela devrait également rendre le traitement des erreurs plus sûr en évitant la divulgation inutile d'informations sur les modules sous-jacents à l'abstraction.

/**
 * @throws UserNotFoundException
 */
public function getUser($username)
{
    try {
        $user = someFunction('SELECT ....', $username);
    } catch (DatabaseException $dbe) {

        /* Re-throw since a database exception may no longer be
         * meaningful to the caller.
         */
        throw new UserNotFoundException();
    }

    return $user
}
9
Czar Pino

Du point de vue de la maintenance de la documentation, je n’ajouterais que les lignes @throw pour les exceptions spécifiquement levées, sans quoi votre documentation ne serait plus à jour.

6
acutesoftware

Numéro deux , mais peut-être lancer avant le retour car les actions de lancer auront lieu avant le retour ...

0
tfont