尝试救援不会没有发现错误

时间:2018-02-15 15:05:14

标签: elixir

  def page_request(url, proxy) do
    uri = URI.parse(proxy)
    case uri.host do
      nil -> raise "Host nil! #{proxy}"
      _ ->
        options =
        case uri.scheme do
            "socks5" -> default_params() ++ [proxy: {:socks5, String.to_charlist(uri.host), uri.port}]
            _-> default_params() ++ [proxy: String.to_charlist(proxy)]
        end
        try do #36 line!
          case HTTPoison.request(:get, String.to_charlist(url), "", [], options) do
            {:ok, response} ->
              %HTTPoison.Response{headers: header, body: body} = response
              gzipped = Enum.any?(header, fn (kv) ->
                case kv do
                  {"Content-Encoding", "gzip"} -> true
                  {"Content-Encoding", "x-gzip"} -> true
                  _ -> false
                end
              end)
              case body do
                nil -> {:ok, %{}}
                _ ->
                  if gzipped do
                    {:ok, :zlib.gunzip(body)}
                  else
                    {:ok, body}
                  end
              end
            {:error, reason} ->
              {:error, reason}
          end
        rescue
          error -> {:error, error}
        end
    end
  end

我无法理解为什么try..rescue没有发现错误?

15:34:24.537 [error] GenServer MyWeb.Worker1 terminating
** (ArgumentError) argument error
    (kernel) gen_tcp.erl:150: :gen_tcp.connect/4
    (hackney) /home/book/my_web/deps/hackney/src/hackney_connect.erl:247: :hackney_connect.do_connect/5
    (hackney) /home/book/my_web/deps/hackney/src/hackney.erl:354: :hackney.send_request/2
    (hackney) /home/book/my_web/deps/hackney/src/hackney.erl:810: :hackney.redirect/2
    (hackney) /home/book/my_web/deps/hackney/src/hackney.erl:742: :hackney.maybe_redirect1/3
    (hackney) /home/book/my_web/deps/hackney/src/hackney.erl:362: :hackney.send_request/2
    (httpoison) lib/httpoison/base.ex:439: HTTPoison.Base.request/9
    (my_web) lib/my_web.ex:37: MyWeb.page_request/2
Last message: :work
State: nil

我认为此代码应该捕获任何错误

但在iex工作:

Interactive Elixir(1.6.0) - 按Ctrl + C退出(键入h()ENTER以获取帮助)

iex(1)> try do
...(1)> raise ArgumentError
...(1)> rescue
...(1)> error -> {:error, error}
...(1)> end
{:error, %ArgumentError{message: "argument error"}}

我浏览了documentation,但找不到答案

elixir 1.6.1

示例网址http://google.com

  defp default_params(timeout \\ 25) do
      [ssl: [verify: :verify_none],
      timeout: timeout*1000,
      recv_timeout: timeout*1000,
      connect_timeout: timeout*1000,
      follow_redirect: true,
      hackney: [pool: false, insecure: true]]
  end

2 个答案:

答案 0 :(得分:0)

要在此使用try rescue,您应该使用HTTPoison.request!,这会引发错误,而不是HTTPoison.request,会返回{:ok, result}{:error, error}

返回rescue元组时,只有当某些{:error, error}被引发时,才会触发Error子句。

答案 1 :(得分:0)

我不认为ArgumentError在您的区块中被提升,而是:hackney MyWeb.WebWorker1可能是一个单独的过程。您无法从单独的流程中拯救异常。

HTTPoison异步吗?我打赌它仍然会返回错误。如果您在Logger案例中添加了:error行,相信您会在那里看到错误消息:

{:error, reason} ->
  Logger.debug(inspect(reason))
  {:error, reason}