Почему Net :: HTTP возвращает 500, когда сервер возвращает 503? - PullRequest
1 голос
/ 03 октября 2019

(Этот вопрос заменяет этот , надеюсь, более качественной информацией.)

У меня есть три сервера, которые я собираюсь назвать Алисой, Чарли,и Гарри (Гарри - настоящее прозвище сервера, чтобы не запутаться). Все они общаются друг с другом, выполняя довольно сложный процесс аутентификации:

  • Клиент выполняет последовательность из трех запросов через Алису к Гарри.
  • На третьем Гарри делаетпозвоните Чарли.
  • Чарли подвержен таймаутам в периоды интенсивного движения. Если это так, Гарри возвращает Алисе 503 с заголовком Retry-After.
  • Гарри - это , возвращающий 503, я подтвердил это в собственных журналах.
  • Алиса не получает 503, а 500, и без заголовка.
  • Другие клиенты Алисы (которые я не контролирую) обрабатывают500 так же, как и другие ошибки, которые я в конечном итоге пытаюсь исправить.

Некоторая дополнительная информация, например, которую я смог установить:

  • Алиса прокси вызывает Гарри, используя RestClient, который использует Net::HTTP под капотом.
  • Использование Net::HTTP напрямую дает тот же результат.
  • Это не зависит от конкретной среды;У меня была эта проблема как в Производстве, так и в Разработке.
  • Я пытался смоделировать Алису с помощью Почтальона, но пока мне не повезло;На данный момент трафик Чарли тише, и я не могу форсировать или симулировать тайм-аут, поэтому пока я получаю только 200 ответов от Гарри.
  • Исправление тайм-аутов Чарли, очевидно, было бы идеальным,но я не контролирую аппаратные средства Чарли.

Есть ли что-то, что я могу изменить в Алисе, чтобы он правильно обнаруживал Гарри 503?

Или, возможно, что-то в Гарри меняет 503 на 500 после того, как оно возвращено и зарегистрировано?

Вот код Алисы для этого третьего вызова, если это вероятнопомочь, но ничего не выскакивает на меня;Мне было интересно, если RestClient или Net::HTTP имеет конфигурацию, о которой я не знаю.

http_verb = :post
args = [ # actually constructed differently, but this is a reasonable mock up
  'https://api.harry/path?sso_token=token',
  '',
  {
    'content_type' => 'application/json',
    'accept' => '*/*',
    # some other app-specific headers
  }
]

RestClient.send(http_verb, *args) do |response, request, result, &block|
  # `result` is present and has a 500 code at the start of this block if Harry returns a 503.
  @status_code = result.present? ? result.code : :internal_server_error
  cors.merge!( response.headers.slice(:access_control_allow_origin, :access_control_request_method) )
  @body = response.body
end

1 Ответ

0 голосов
/ 10 октября 2019

Оказывается, что это способ проще и очевиднее, чем кто-либо думал.

A В промежуточном программном обеспечении, отвечающем за возврат 503, возникла отдельная ошибка . Как и в случае любого другого исключения, это было обработано как 500.

То, что вызывало его, было строкой, которая должна была сказать клиенту подождать пять секунд и повторить попытку:

response.headers['Retry-After'] = 5

... какой-то компонент промежуточного программного обеспечения жаловался на undefined method 'each' on 5:Fixnum и начал работать, когда мы изменили 5 на строку.

...