【问题标题】:Catching HTTPoison errors with invalid port range使用无效端口范围捕获 HTTPoison 错误
【发布时间】:2020-01-13 08:04:41
【问题描述】:

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

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

【问题讨论】:

    标签: elixir httpoison


    【解决方案1】:

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

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

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

    我找不到?port 的来源,但我确信它会检查端口是否在界限内(非负且小于 65535)。

    现在你无法处理错误的原因是因为在某些时候exit() 被调用,而process exit 的处理方式应该有所不同:

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

    您遇到了一个未被HTTPoison 库处理的错误并直接传播到您的应用程序,因为除非退出是trapped,否则exit 消息将被传播。

    PS:除非别无选择,否则不应在应用程序中处理此类错误。

    【讨论】:

    • 当且仅HTTPoison 应用程序启动时会发生这种情况,这在很久以前已被弃用。
    • 此外,这实际上破坏了 OTP 合同,底层进程崩溃并且从未重新启动 AFAICT。对远程的后续请求也会崩溃。
    • 我想这是来自 hackney 的错误,由于我不太擅长阅读 erlang 代码,因此无法确定,HTTPoison 只是 hackney 的灵丹妙药包装器。
    【解决方案2】:

    使用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{...}
    

    【讨论】:

    • 或者你可以使用隐式try,credo 鼓励使用它。
    • @Daniel 除非将调用HTTPoison.get/1 的结果分配给一个变量,然后以某种方式进行处理。我们不知道上下文,因此我们不能建议隐含的try
    • 试图处理这样的错误(虽然没有处理): defp fetch(url) do try do Logger.info("Fetching #{url}") HTTPoison.get(url) rescue FunctionClauseError - > Logger.error("试图调用 url #{url} 捕获异常") {:error, ""} end end
    • 抱歉,注释格式错误,不知道如何格式化代码块
    • “未处理”究竟是什么意思?
    猜你喜欢
    • 2016-09-08
    • 1970-01-01
    • 1970-01-01
    • 2018-03-26
    • 1970-01-01
    • 2014-12-30
    • 2013-05-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多