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 будет ожидаемым результатом и мне нужно будет получить, какие-то подробности об этой ошибке. В таком случае, в клиенте мне нужно будет создать экземпляр исключения, записать в его поля эти самые подробности и только потом выбросить его. Не слишком мутно?


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

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 бросить исключение, то оно и в первом примере тоже будет. Только Вы его не обработали.
То есть обработка ошибок АПИ в клиенте зависит от того, в каком виде АПИ возвращает ошибки в клиент.
Ответ написан
Ваш ответ на вопрос

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

Войти через TM ID
Похожие вопросы
VITAL Тольятти
от 70 000 до 100 000 руб.
Tapigo Пермь
от 40 000 до 60 000 руб.
18 июля 2018, в 22:20
4000 руб./за проект
18 июля 2018, в 21:54
1000 руб./в час