Skip to content

Успешный ответ опознаётся как Problem: союз без дискриминатора и не-nilable поля, по которым API шлёт null #19

Description

@corsicanec82

Что происходит

custom_fields.get_by_id на живом аккаунте возвращает объект класса CustomFieldGetByIDResponse::Problem, хотя тело — нормальное описание поля со всеми опциями. Данные не теряются: у экземпляра Problem внутри лежат и type: "select", и name: "stack", и enums. Союз выбрал не тот вариант.

Проверено на 0.6.1, ruby 4.0.6:

resp = client.custom_fields.get_by_id(921_871, entity_type: "leads")
resp.class
# => Amocrm::Models::CustomFieldGetByIDResponse::Problem

Причина

CustomFieldGetByIDResponse — союз из CustomField и Problem без дискриминатора, HTTP-статус в выборе не участвует. Побеждает первый вариант без несовпадений (lib/amocrm/internal/type/union.rb, coerce).

У CustomField несовпадения находятся: code, group_id, currency, tracking_callback, remind, chained_lists объявлены как String/Integer без nilable, а amoCRM штатно шлёт по ним null. Отсутствие ключа схеме не противоречит, явный null — противоречит. Problem совпадает по type и выигрывает.

Сокращённое реальное тело:

{"id":921871,"name":"stack","type":"select","code":null,"group_id":null,"currency":null,
 "tracking_callback":null,"remind":null,"chained_lists":null,"enums":[...]}

Убрать из тела null-поля — союз выбирает CustomField.

Почему это стоит чинить в спеке

Отличить успех от ошибки по классу — единственный способ, который даёт SDK, и он не работает. Обойти можно чтением сырого поля (resp[:enums]), но тогда теряется типизация, ради которой SDK и нужен.

Масштаб: вариант Problem встречается примерно в 140 моделях гема, и всюду та же схема — два полностью опциональных варианта без дискриминатора. Любая ручка, где API отдаёт null по не-nilable полю, молча опознаётся как ошибка.

Что предлагаем

  1. Пометить nilable поля, по которым API штатно шлёт null — прямая причина этого случая.
  2. Развести успешный ответ и ошибку так, чтобы выбор не зависел от полноты тела: дискриминатором или по HTTP-статусу.

Судя по CONTRIBUTING, код генерируется, поэтому правка — в спеке.

Как это проявилось у нас

Справочное поле программы не доезжало ни в одну сделку: код считал справочник недоступным и поле не отправлял. Ошибка молчаливая — заявка уходит, поля нет.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions