Возврат ошибок в API
От: Буравчик Россия  
Дата: 24.06.19 09:05
Оценка:
Какие HTTP status code используются в ваших API?
200, 401, 403, 404 и т.п.

Передаете ли дополнительную информацию об ошибках? Какую?
Код ошибки, текстовое сообщение, на каком языке (русский, английский), дополнительные параметры?

Кодируете ошибки, как? Единая нумерация для всего API, или свои ошибки для каждого endpoint?

Используете какие-то правила для возвратов ошибок?
Например, по аналогии с JSON-RPC, в котором наличие в ответе поля errors означает, что произошла ошибка при обработке запроса.

Что возвращаете, если клиент запрашивает существующий ресурс, к которому запрещен доступ:
404 или 403?

В общем, научите как надо возвращать информацию об ошибках в API
Best regards, Буравчик
Re: Возврат ошибок в API
От: MadHuman Россия  
Дата: 24.06.19 18:39
Оценка: 92 (3)
Здравствуйте, Буравчик, Вы писали:

Б>Какие HTTP status code используются в ваших API?

если ошибка клиента (неправильный запрос) — 4**. неправильный запрос — это значит что клиенту не следует повторять запрос в том же виде, без изменений.
если сервера — 500 (это перегрузка сервера, неожидаемые ошибки при обработке реквеста). ошибка сервера — это когда запрос составлен верно, но сервер по каким-то причинам не смог.

Б>Передаете ли дополнительную информацию об ошибках? Какую?

если для целей обработки ошибки на клиенте нужна эта доп. информация — передаём.
можно в заголовке, типа X-Reason: какой-то доп. код/идентификатор поясняющий что не так.

Б>Код ошибки, текстовое сообщение, на каком языке (русский, английский), дополнительные параметры?

это зависит. если система (и апи) в основном для русскоязычных — можно на русском.
всё дополнительное определяется конкретикой, если вызвающей стороне нужна/плезна доп. информация о том, что не так — можно включить.

Б>Что возвращаете, если клиент запрашивает существующий ресурс, к которому запрещен доступ:

Б>404 или 403?
403 ближе к сути, но есть нюанс, если надо скрыть что такой ресурс существует (защита от перебора), то можно и 404.

есть практика http использовать в качестве транспорта (аля JSON-RPC), в этом случае ответ всегда 200 и инфа об ошибке в теле ответа.
но наша практика показала, что использование http кодов ответа тоже норм, особенно с учетом, что их в любом случае придется обрабатывать (может оказаться реально плохой запрос, прокси, и прочее)
то лучше тогда уж сразу на них ориентироваться. бытует мнение что кодов недостаточно (это так), но если в хидере или теле возвращать доп. информацию (если надо), то всё ок.

также использование хттп статус кодов, упрощает анализ логов веб-сервера. сразу можно фильтровать ошибки, иначе придется что-то дополнительно мутить.
Отредактировано 24.06.2019 18:41 MadHuman . Предыдущая версия .
Re: Возврат ошибок в API
От: vsb Казахстан  
Дата: 24.06.19 18:48
Оценка: -2
Последний раз использовал код 400 и возврат кода ошибки в читаемом виде например user not found с типом text/plain. Минус в том, что сервер в определённых условиях тоже возвращает код 400. Поэтому хочу переделать на какой-нибудь другой код из разряда 4xx, пока не выбрал, какой (большого значения не имеет, лишь бы не пересекался со стандартными кодами, которые может отдавать сервер).

Считаю пересечение неудачной идеей. 404 например отдавать не стоит, чтобы клиент мог чётко отличить кривую конфигурацию сервера от "правильного" ошибочного ответа. Хотя народу вроде нравится...
Re[2]: Возврат ошибок в API
От: Stalker. Австралия  
Дата: 24.06.19 23:28
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>Считаю пересечение неудачной идеей. 404 например отдавать не стоит, чтобы клиент мог чётко отличить кривую конфигурацию сервера от "правильного" ошибочного ответа. Хотя народу вроде нравится...


семантически отсутствие пользователя users/99 равнозначно неверному адресу usrs/99, плюс в теле ответа будет сообщение, по которому можно понять что именно отсутствует
Re[3]: Возврат ошибок в API
От: vsb Казахстан  
Дата: 25.06.19 03:24
Оценка:
Здравствуйте, Stalker., Вы писали:

vsb>>Считаю пересечение неудачной идеей. 404 например отдавать не стоит, чтобы клиент мог чётко отличить кривую конфигурацию сервера от "правильного" ошибочного ответа. Хотя народу вроде нравится...


S>семантически отсутствие пользователя users/99 равнозначно неверному адресу usrs/99


Не согласен. Если я забыл задеплоить варку, у меня внезапно куда-то исчезли все юзеры? Не так ведь. Это как я на RSDN зайду, а мне напишут, что тема не существует, вместо того, чтобы написать, что форум перезагружают.

S>плюс в теле ответа будет сообщение, по которому можно понять что именно отсутствует


Ну т.е. предлагается анализировать не код ответа, а тело ответа? Но от этого же хочется уйти вроде как.
Re: Возврат ошибок в API
От: RushDevion Россия  
Дата: 25.06.19 09:07
Оценка: 180 (9) +1
Здравствуйте, Буравчик, Вы писали:

Б>Какие HTTP status code используются в ваших API?

Б>200, 401, 403, 404 и т.п.
Используем все.
200 (OK) — все OK, в теле ответа будут данные
201 (Created) — все ОК, новая сущность создана. Обычно в ответ на POST, в хидере Location — адрес новой сущности. В теле ответа могут быть данные.
202 (Accepted) — все ОК, мы твой запрос приняли, обработаем позже (e.g. положили в очередь). В теле ответа могут быть данные.
204 (No Content) — все ОК, мы твой запрос обработали, но контент вернуть не можем (обычно в ответе на DELETE)
308 (Permanent Redirect) — мы тут немного поменяли схему роутов, иди в другое место
400 (Bad Request) — с входящим запросом что-то не так (e.g. не прошла валидация, не хватает данных, неправильный формат и т.п.)
401 (Unauthorized) — мы не знаем, кто ты такой, иди авторизуйся
403 (Forbidden) — авторизовался? молодец! Но прав на доступ конкретно к этому ресурсу у тебя все равно не хватает
404 (Not Found) — ресурс не найден
409 (Conflict) — твоя локальная копия данных устарела (обычно для реализации оптимистичной блокировки в ответ на POST/PUT/PATCH)
429 (Too Many Requests) — если есть реализуется какой-то вариант rate-limiting'a
500 (Internal Server Error) — упс, мы где-то облажались. Уже работаем над этим.

Б>Передаете ли дополнительную информацию об ошибках? Какую?

Б>Код ошибки, текстовое сообщение, на каком языке (русский, английский), дополнительные параметры?
Да. Сама модель ошибки в теле запроса, e.g.
{
  "http_code": 403,          // Дублируем тут, для удобства клиента
  "code": "AccountBlocked",   // Код ошибоки.
  "message": "The account 'xxx' is blocked",  // На языке запроса (Accept-хидер), по умолчанию - английский
  "validation_errors": [
     { "field1": "error text1" },
     { "field2": "error text2" }
  ]
}



Б>Кодируете ошибки, как? Единая нумерация для всего API, или свои ошибки для каждого endpoint?

Обычные текстовые строки.
Есть какой-то глобальные набор ошибок (типа аккаунт заблокирован, требуется авторизация, входные данные некорректны и т.п.).
Иногда добавляются endpoint-специфичные.

Б>Используете какие-то правила для возвратов ошибок?

Б>Например, по аналогии с JSON-RPC, в котором наличие в ответе поля errors означает, что произошла ошибка при обработке запроса.
Есть JSON/XML-схема для кода ошибки.
Она описывается в SWAGGER-документации.

Б>Что возвращаете, если клиент запрашивает существующий ресурс, к которому запрещен доступ:

Б>404 или 403?
403

Б>В общем, научите как надо возвращать информацию об ошибках в API

Так, чтобы клиентам твоего API было удобно ей пользоваться
Re: Возврат ошибок в API
От: Ночной Смотрящий Россия  
Дата: 25.06.19 12:44
Оценка: 14 (1)
Здравствуйте, Буравчик, Вы писали:

Б>Какие HTTP status code используются в ваших API?

Б>200, 401, 403, 404 и т.п.

Много разных. Помимо перечисленных точно используется 201, 202, 400, 409, 500.

Б>Передаете ли дополнительную информацию об ошибках?


Да.

Б> Какую?


Уникальный код, severity, источник, нелокализуемое сообщение на английском, название параметра если применимо, значения подстановок для локализованного сообщения. В отладочных версиях еще stacktrace.
А вообще есть RFC 7807.

Б>Кодируете ошибки, как? Единая нумерация для всего API, или свои ошибки для каждого endpoint?


Вообще не числа, а символьные коды.

Б>Что возвращаете, если клиент запрашивает существующий ресурс, к которому запрещен доступ:

Б>404 или 403?

403 разумеется.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[2]: Возврат ошибок в API
От: Ночной Смотрящий Россия  
Дата: 25.06.19 12:46
Оценка:
Здравствуйте, MadHuman, Вы писали:

MH>если сервера — 500 (это перегрузка сервера


Для перегрузки есть специальный код, 429. И еще желательно хидер Retry-After.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[3]: Возврат ошибок в API
От: MadHuman Россия  
Дата: 25.06.19 13:35
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

MH>>если сервера — 500 (это перегрузка сервера

НС>Для перегрузки есть специальный код, 429.
да, но 429 (Too Many Requests) — для более узкого случая, когда хотят на сервере ограничить частоту реквестов от клиента. в этом случае да, лучше его.
я имел ввиду несколько другие ситуации, например для обработки реквеста надо сходить в базу, база перегружена и ответила соотвествующей ошибкой.
или сервер под высокой нагрузкой и реквест клиента по каким-то причинам (особенно связанным с данными клиентам) выполняется слишком долго и его прервали.
или сервер уже под высокой нагрузкой и пока лучше не начинать обработку новых запросов.
типа такого.

НС>И еще желательно хидер Retry-After.
Re[4]: Возврат ошибок в API
От: Ночной Смотрящий Россия  
Дата: 25.06.19 13:45
Оценка: -2
Здравствуйте, MadHuman, Вы писали:

MH>да, но 429 (Too Many Requests) — для более узкого случая


В HTTP RFC ничего про более узкие случаи не сказано.

MH>, когда хотят на сервере ограничить частоту реквестов от клиента. в этом случае да, лучше его.

MH>я имел ввиду несколько другие ситуации, например для обработки реквеста надо сходить в базу, база перегружена и ответила соотвествующей ошибкой.
MH>или сервер под высокой нагрузкой и реквест клиента по каким-то причинам (особенно связанным с данными клиентам) выполняется слишком долго и его прервали.
MH>или сервер уже под высокой нагрузкой и пока лучше не начинать обработку новых запросов.

Не вижу принципиального отличия. Если ты понял что проблема именно в перегруженности — 429 самое то, неважно какой именно компонент перегружен. Потому что реакция клиента во всех случаях одна — попробовать попозже или сказать что сервер перегружен.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[5]: Возврат ошибок в API
От: MadHuman Россия  
Дата: 25.06.19 15:53
Оценка: 6 (1)
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Здравствуйте, MadHuman, Вы писали:


MH>>да, но 429 (Too Many Requests) — для более узкого случая


НС>В HTTP RFC ничего про более узкие случаи не сказано.


в RFC сказано так

The 429 status code indicates that the user has sent too many
requests in a given amount of time ("rate limiting").

The response representations SHOULD include details explaining the
condition, and MAY include a Retry-After header indicating how long
to wait before making a new request.



НС>Не вижу принципиального отличия.

я вижу отличие в следующем — тут проблема из-за клиента, он часто шлет запросы (поэтому и код выбрали 4**).
а в случае перегрузки сервера или какого-то компонента, клиент может быть и не причем.
его может несколько обескуразить, ответ, что это он has sent too many requests in a given amount of time.
ведь он может сделал 1-й реквест.

НС>Потому что реакция клиента во всех случаях одна — попробовать попозже или сказать что сервер перегружен.

для этого норм упомянутый вами ранее хидер Retry-After.
его и для 500 и для 429 стоит смотреть.
Re[5]: Возврат ошибок в API
От: · Великобритания  
Дата: 25.06.19 16:41
Оценка: 4 (1) +6
Здравствуйте, Ночной Смотрящий, Вы писали:

MH>>, когда хотят на сервере ограничить частоту реквестов от клиента. в этом случае да, лучше его.

MH>>я имел ввиду несколько другие ситуации, например для обработки реквеста надо сходить в базу, база перегружена и ответила соотвествующей ошибкой.
MH>>или сервер под высокой нагрузкой и реквест клиента по каким-то причинам (особенно связанным с данными клиентам) выполняется слишком долго и его прервали.
MH>>или сервер уже под высокой нагрузкой и пока лучше не начинать обработку новых запросов.
НС>Не вижу принципиального отличия. Если ты понял что проблема именно в перегруженности — 429 самое то, неважно какой именно компонент перегружен. Потому что реакция клиента во всех случаях одна — попробовать попозже или сказать что сервер перегружен.
Принципиальное отличие, что возвратить 4xx клиенту — обвинить клиента в том, что он что-то делает не так. А 5xx — это что-то не так с сервером.
При перегрузке сервера не по вине данного клиента — надо возвращать 503 Service Unavailable. Собственно это как раз то, что обычно делают в такой ситуации всякие лоад-балансеры и проксяки.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[6]: Возврат ошибок в API
От: Ночной Смотрящий Россия  
Дата: 25.06.19 17:34
Оценка:
Здравствуйте, ·, Вы писали:

·>Принципиальное отличие, что возвратить 4xx клиенту — обвинить клиента в том, что он что-то делает не так. А 5xx — это что-то не так с сервером.


Чем при этом должна отличаться реакция клиента?
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[7]: Возврат ошибок в API
От: RushDevion Россия  
Дата: 25.06.19 19:07
Оценка: +1
НС>·>Принципиальное отличие, что возвратить 4xx клиенту — обвинить клиента в том, что он что-то делает не так. А 5xx — это что-то не так с сервером.
НС>Чем при этом должна отличаться реакция клиента?

Главным образом retry-политикой и способом обработки ошибки, e.g.
1) 500 Internal Server Error — заретраиться сразу, но не более 3-х попыток.
Т.к., возможно, ошибка либо разовая (e.g. таймаут сработал, GC невовремя запустился и т.п.), либо случилась на конкретной ноде (если у нас кластер).
Значит, есть шанс, что следующий запрос придет на другую ноду и там все будет хорошо.
Ну а если три раза подряд облом — скорей всего вся система лежит и больше от нее ничего не добьешься.
2) 503 Service Unavailable, 529 To Many Requests — мы вот-вот положим сервер своими запросами, надо бы замедлиться.
Здесь подойдет бесконечный ретрай в рамках общего таймаута, с эспоненциальным ростом времени ожидания между попытками.
Т.е. первый ретрай — через 1сек., потом через 2, потом через 4 и т.д.
3) 4xx — тут ретраиться бесполезно, т.к. ответ не изменится. Остается только обработать ошибку.
400 Bad Request — можно распарсить валидационные ошибки из тела ответа и отобразить их в UI
404 Not Found — показать сообщение "Запись не найдена"
403 Forbidden — показать сообщение "Доступ запрещен", возможно записать в Audit Log
409 Conflict — показать сообщение "Ваша копия данных устарела. Обновить? Да/Нет."
Отредактировано 25.06.2019 19:10 RushDevion . Предыдущая версия .
Re: Возврат ошибок в API
От: KOLRH Финляндия  
Дата: 26.06.19 05:57
Оценка: +1
Здравствуйте, Буравчик, Вы писали:

Б>Какие HTTP status code используются в ваших API?

Б>200, 401, 403, 404 и т.п.
Стараемся использовать все. Зачем придумывать колесо заново и большая часть клиентов умеет их отрабатывать на достаточном уровне.
Хотел бы еще дополнить лист кодом 422 (Unprocessable Entity). Использую когда запрос вроде синтаксически правильный, но логически нет. Например клиент посылает адрес, в котором почтовый код не соответствует городу или улице.

Б>Передаете ли дополнительную информацию об ошибках? Какую?

Б>Код ошибки, текстовое сообщение, на каком языке (русский, английский), дополнительные параметры?
Б>Кодируете ошибки, как? Единая нумерация для всего API, или свои ошибки для каждого endpoint?
Обязательно передаю в теле ответа. Текстовое сообщение на английском для логов и код ошибки, по которому клиент сможет показать ошибку пользователю на желаемом языке.
Нумерация глобальная для общих ошибок, и расширяется ендпойнт-специфичными.

Б>Используете какие-то правила для возвратов ошибок?

Б>Например, по аналогии с JSON-RPC, в котором наличие в ответе поля errors означает, что произошла ошибка при обработке запроса.

Б>Что возвращаете, если клиент запрашивает существующий ресурс, к которому запрещен доступ:

Б>404 или 403?
403

Б>В общем, научите как надо возвращать информацию об ошибках в API

Сами учимся все время
api error
Re[8]: Возврат ошибок в API
От: Ночной Смотрящий Россия  
Дата: 26.06.19 08:24
Оценка:
Здравствуйте, RushDevion, Вы писали:

RD>Главным образом retry-политикой и способом обработки ошибки, e.g.


Речь была не вообще про все коды, а исключительно про 429 vs 500 при перегрузке чего то там внутри сервиса.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[4]: Возврат ошибок в API
От: Stalker. Австралия  
Дата: 01.07.19 06:25
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>Не согласен. Если я забыл задеплоить варку, у меня внезапно куда-то исчезли все юзеры? Не так ведь. Это как я на RSDN зайду, а мне напишут, что тема не существует, вместо того, чтобы написать, что форум перезагружают.


не знаю что такое "задеплоить варку", но при "кривой" конфигурации могут легко прийдти и 500-коды, и вообще на практике не требуется клиентам отличать кривую конфигурацию от некривой

vsb>Ну т.е. предлагается анализировать не код ответа, а тело ответа? Но от этого же хочется уйти вроде как.


зачем куда-то уходить от тела ответа? Оно совершенно точно нужно. Максимум что можно добавить это коды типов ошибок, и то, только если в приложении требуется их по разному обрабатывать (при возврате кода 400 высвечивать разные контролы в зависимости от типа ошибки — неверный телефон или email итп)
Re[5]: Возврат ошибок в API
От: vsb Казахстан  
Дата: 01.07.19 10:08
Оценка:
Здравствуйте, Stalker., Вы писали:

vsb>>Не согласен. Если я забыл задеплоить варку, у меня внезапно куда-то исчезли все юзеры? Не так ведь. Это как я на RSDN зайду, а мне напишут, что тема не существует, вместо того, чтобы написать, что форум перезагружают.


S>не знаю что такое "задеплоить варку"


Скопировать .war архив в нужную папочку.

S>но при "кривой" конфигурации могут легко прийдти и 500-коды, и вообще на практике не требуется клиентам отличать кривую конфигурацию от некривой


Мне требуется. Если сервак не пашет, я хочу юзеру показать, что сервак не пашет, а не "тема удалена или перемещена". 500 коды это хорошо, но приходят 404.

S>зачем куда-то уходить от тела ответа? Оно совершенно точно нужно. Максимум что можно добавить это коды типов ошибок, и то, только если в приложении требуется их по разному обрабатывать (при возврате кода 400 высвечивать разные контролы в зависимости от типа ошибки — неверный телефон или email итп)


Ну как минимум в приложении нужно высветить месседж на нужном языке. Для этого текстовый код и нужен. Если разная обработка нужна, по этим текстовым кодам можно ифы накидать какие надо.

В общем раз парсим текст ответа, значит в коде сообщения никакого смысла нет. Договориться про какой-нибудь 499, чтобы с кодом сервера не пересекаться и всё.
Отредактировано 01.07.2019 10:09 vsb . Предыдущая версия . Еще …
Отредактировано 01.07.2019 10:08 vsb . Предыдущая версия .
Re[6]: Возврат ошибок в API
От: Stalker. Австралия  
Дата: 02.07.19 03:13
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>В общем раз парсим текст ответа, значит в коде сообщения никакого смысла нет. Договориться про какой-нибудь 499, чтобы с кодом сервера не пересекаться и всё.


текст сообщения "парсится" только если внутри ответа 404 надо разные вещи делать в зависимости от внутреннего кода, это будут в основном только формы с данными, где надо подсвечивать разные поля в зависимости от конкретной ошибки бизнес-логики, обычно этого и не надо
Re[9]: Возврат ошибок в API
От: Аноним931 Германия  
Дата: 10.07.19 07:18
Оценка: +1
НС>Речь была не вообще про все коды, а исключительно про 429 vs 500 при перегрузке чего то там внутри сервиса.

И на это выше уже дали абсолютно правильный ответ:

возвратить 4xx клиенту — обвинить клиента в том, что он что-то делает не так. А 5xx — это что-то не так с сервером.
При перегрузке сервера не по вине данного клиента — надо возвращать 503 Service Unavailable.

"Больше 100кмч можно ехать на автобане в любом ряду кроме правого крайнего" (c) pik
"В германии земля в частной собственности" (c) pik
"Закрывать школы, при нулевой смертности среди детей и подростков, это верх глупости" (c) Abalak
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.