Перехват ошибок HTTPoison с неверным диапазоном портов - PullRequest
1 голос
/ 13 января 2020

Обнаружена ситуация, когда URL-адрес, переданный для получения, содержит недопустимый порт

iex> HTTPoison.get("http://example.com:650000")

** (FunctionClauseError) no function clause matching in :inet_tcp.do_connect/4
   (kernel) inet_tcp.erl:113: :inet_tcp.do_connect({127, 0, 0, 1}, 650000, [{:packet, :raw}, {:active, false}, :binary], 8000)
   (kernel) gen_tcp.erl:185: :gen_tcp.try_connect/6
   (kernel) gen_tcp.erl:163: :gen_tcp.connect/4

. Кажется, я не могу поймать / спасти этот сценарий.

Ответы [ 2 ]

1 голос
/ 13 января 2020

После того, как копание глубже, похоже, ошибка возникает из-за того, что вы используете номер порта, который больше максимально допустимого значения.

Порты должны находиться в диапазоне 0..65535, если мы go найдем исходный код функции, выдавшей исключение, мы можем заметить следующее:

do_connect(Addr = {A,B,C,D}, Port, Opts, Time)
  when ?ip(A,B,C,D), ?port(Port)

Я не могу найти источник для ?port, однако я уверен, что он проверяет, что порт находится в границах (неотрицательных и меньше 65535).

Теперь причина, по которой вы не смогли обработать ошибку, заключается в том, что в некоторых случаях точка exit() вызывается и процесс выхода должен обрабатываться немного иначе:

try do
  result = HTTPoison.get "http://example.com:6500000"
catch
  :exit, reason -> reason
end

Вы столкнулись с ошибкой, которая не обрабатывается библиотекой HTTPoison и распространяется на ваш приложения, так как exit сообщения распространяются, если выходы не trapped .

PS: вы не должны обрабатывать ошибки, подобные этой, в вашем приложении, если нет другого выбора.

1 голос
/ 13 января 2020

Использование Kernel.SpecialForms.try/1.

try do
  HTTPoison.get("http://example.com:650000")
rescue
  e in [FunctionClauseError] ->
    IO.inspect(e, label: "Error")
    nil
end

#⇒ Error: %FunctionClauseError{...}
...