1

遇到传给get的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

似乎我无法从这种情况中捕捉/拯救。

4

2 回答 2

1

在深入挖掘之后,错误似乎来自于您使用的端口号大于最大可接受值的事实。

端口应该在范围内0..65535,如果我们查看引发异常的函数的源代码,我们可以注意到以下内容:

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消息会传播,除非出口被捕获

PS:除非没有其他选择,否则您不应在应用程序中处理此类错误。

于 2020-01-13T11:46:05.570 回答
1

使用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{...}
于 2020-01-13T08:19:34.323 回答