Рекомендации: использование @throws в php-doc, и как это можно было бы обрабатывать

Скажем, у меня есть класс с таким способом:

/*
 *
 * 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
}

Теперь скажем, что someFunction может генерировать InvalidArgumentException/RuntimeException/PDOException по причинам XYZ. Что мне делать? А что нет?

Номер 1

Добавьте все возможные исключения, которые могут бросать someFunction в 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 ...
 */

Номер 2

Добавьте блок try-catch, чтобы гарантировать, что метод должен генерировать исключения, ТОЛЬКО документированные

/*
 *
 * 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
}

Номер 3

Не делай ничего.

Ответы

Ответ 1

Лично я бы рассматривал обращение @throws, похожее на проверенные исключения Java

Способ, которым это работает в Java, заключается в том, что в основном исключения, которые наследуются от RuntimeException, могут быть выброшены и не должны обрабатываться. Любые другие типы исключений должны иметь блок try-catch для их обработки. Этот код обработки должен находиться в вызывающем абоненте.

В основном в PHP вроде бы:

Когда метод имеет аннотацию @throws, вы должны добавить код для обработки его исключений.

Любые исключения, которые не упоминаются, являются необязательными для обработки в вызывающем коде.


Теперь я не 100% следую этому принципу сам. Вся обработка исключений вещь вроде до предпочтения программиста, но это всего лишь некоторые мысли о том, как я думаю, что это можно было бы обработать разумным образом.

Ответ 2

Что касается документации, если функция явно выдает исключение, она должна быть включена в документацию по функциям. Таким образом, для каждого оператора throw в документации PHP должен быть соответствующий @throws.

Что касается обработки, если есть какие-то операции, которые должны выполняться при вызове исключения, а затем поймать его. В противном случае, пусть это пузырится - если есть инструкция catch, которая будет обрабатывать ее позже.

Ответ 3

С точки зрения обслуживания документации я бы добавил только строки @throw для исключений, которые были специально выбраны, иначе вы быстро устанете свою документацию.