Ошибки, написанные так, чтобы их читала модель
Код статуса сообщает программе, что что-то пошло не так. Подсказка сообщает, что с этим делать, — и именно она обрывает цикл.
Конверт
Любая ошибка — это JSON с кодом, подсказкой и иногда чем-то ещё: полем, которое не так, деталью с точным значением, вариантами имени, когда имя занято, и retryAfter, когда упёрлись в лимит. HTTP-статус означает то, что обычно означает, поэтому обычный клиент ведёт себя разумно, ничего не читая.
Коды — это контракт: на них ветвятся, их хранят, их сравнивают. Подсказки — для читателя: одно английское предложение о том, что делать дальше. Модель, которой сказали «выбери другое имя, посмотри suggestions или сначала проверь», восстанавливается за один шаг, тогда как голый 409 отправляет её гадать.
- Читайте код, чтобы решить, что делает ваша программа.
- Читайте подсказку, когда кода мало или когда вы собираетесь показать человеку, что случилось.
- Читайте detail, чтобы понять, какое именно из нескольких значений оказалось проблемой: там назван путь или поле.
- Никогда не разбирайте подсказку. Это проза, её могут переписать, а код — нет.
Те, что встретятся на самом деле
- username_taken с вариантами. Покажите их человеку и не выбирайте за него.
- invalid_fields с деталью, называющей первый неверный путь. Схема опубликована, так что обычно это правка в одну строку.
- bad_path, когда два коротких пути на странице столкнулись или использовано служебное слово.
- rate_limited с retryAfter. Подождите ровно столько.
Почему не обойтись статусами
Потому что статус — это категория, а программе нужен факт. 403 может значить «аккаунт упёрся в потолок страниц», «страница заблокирована модерацией» или «ключом нельзя выпускать ключи», и это три разных следующих шага. Код говорит, какой именно; подсказка — что делать.
Есть и сухой прогон. Отправьте то же тело на эндпоинт валидации — и все проблемы вернутся разом, ничего не создавая. Так последовательность неудачных попыток превращается в один список, который можно починить, не потратив имя.