happyproff
@happyproff
Счастливый веб-разработчик

Дизайн клиента API. Как лучше возвращать ошибки от API?

Приветствую.


Есть вопрос по дизайну работы с ошибками в клиенте некоего API. Как лучше, красивее, проще в работе, более true, более модно-стильно-молодёжно, как вам, разработчикам больше понравилось бы?

$result = $apiFacade->getData();
if ($result->isSuccess()) {
    echo 'success: ' . $result->getData() . PHP_EOL;
} else {
    if (ApiClient::ERROR_NOT_ENOUGHT_UNITS === $result->getError()->getCode()) {
        // some actions for this error
    } elseif (ApiClient::ERROR_OBJECT_NOT_EXISTS === $result->getError()->getCode()) {
        // some actions for this error
    } else {
        // some actions for other errors
    }
}


try {
    $result = $apiFacade->getData();
} catch (ApiNotEnoughtUnitsException $exception) {
    // $exception->getCode() вернёт код ошибки
    // $exception->getMessage() вернёт текст ошибки
    // some actions for this error
} catch (ApiObjectNotExistsException $exception) {
    // some actions for this error
} catch (ApiException $exception) {
    // some actions for other errors
}
echo 'success: ' . $result . PHP_EOL;



Речь здесь идёт об ошибках, получаемых в ответе API.


На мой взгляд, бросаться исключениями — хорошо. Если где-то в приложении я не обработаю исключение, его поймает глобальный exception_handler и я об этом узнаю из логов или оповещений. С другой стороны, существует вероятность возникновения ситуации, когда ошибка API будет ожидаемым результатом и мне нужно будет получить, какие-то подробности об этой ошибке. В таком случае, в клиенте мне нужно будет создать экземпляр исключения, записать в его поля эти самые подробности и только потом выбросить его. Не слишком мутно?


Кто сталкивался, ещё какие есть плюсы и минусы у этих подходов?
  • Вопрос задан
  • 4740 просмотров
Пригласить эксперта
Ответы на вопрос 5
Suvitruf
@Suvitruf
Java/node.js/game-dev
Исключения и какой-нибудь глобальный обработчик.

p.s. if на switch бы заменить)

switch($result->getError()->getCode()) {
      case  ApiClient::ERROR_NOT_ENOUGHT_UNITS:
        //...
        break;
      case ApiClient::ERROR_OBJECT_NOT_EXISTS:
        //...
        break;
      default:
        //...
        break;
}
Ответ написан
EugeneOZ
@EugeneOZ
Бросаться исключениями — плохо, потому что незначительная и никого не интересующая 404 при удалении объекта может оборвать стек выполнения и выдать пользователю бээээ на экран. Исключениями бросаются в языках со строгой типизацией, потому что там нельзя «вдруг» вернуть false вместо ожидаемого типа. В Go эта проблема решена тем, что там можно вернуть несколько значений.
Ответ написан
Stdit
@Stdit
Я сталкивался. Когда-то тоже ломал голову над этим вопросом, и не нашел однозначного ответа, потому что всякий способ имеет как сильные, так и слабые стороны. Пробовал разные варианты, включая велосипеды, возврат кода ошибки и даже возврат ассоциативных массивов типа {status, result}. Многие не рекомендовали бросать исключения, аргументируя тем, что исключение должно оставаться исключением, а не становиться бизнес-логикой (в том числе, когда параметры исключения передаются в его конструктор при его бросании, в зависимости от типа исключения). В целом же, на практике оказалось, что это достаточно удобно, уменьшает количество условий, проверок, код становится короче и читается проще, багов становится меньше. На скорости работы почти не отражается. В нескольких поздних проектах на php обработка ошибок модели была сделана похожим образом. При реализации rest-api на эту модель достаточно просто создаются контроллеры. Возможно у кого-то есть другой опыт и он поделится негативными впечатлениями от исключений, но после выбора такого подхода мне жалеть не приходилось. Так что, как разработчику, такой способ контроля ошибок вполне бы подошел.
Ответ написан
@anitspam
Если ошибка неустранимая силами клиента и он завершает работу после возникновения такой ошибки, то это исключительная ситуация, работаем с исключениями, пользователю показываем «Попробуйте позже», самому API сообщаем, что «я завершился» (если этому API надо что-нибудь сообщать).

Если клиент предполагает работать дальше (не хватает денег на постройку? пользователю показываем «Не хватает денег», API сообщаем «ок, не хватает, так хватает», клиент продолжает работать с текущим количеством денег), то это не исключение, а нормальная работа.
Ответ написан
@serega_kaktus
Программист-самоучка, фрилансер
Может я ошибаюсь, но в Вашем примере все зависит от
$apiFacade->getData()

Если в этом методе может быть брошено исключение, то нужно их обрабатывать. Если ошибка и код всегда возвращаются как результат работы метода getData, то нужно использовать первый вариант. Если getData бросить исключение, то оно и в первом примере тоже будет. Только Вы его не обработали.
То есть обработка ошибок АПИ в клиенте зависит от того, в каком виде АПИ возвращает ошибки в клиент.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы