elixirhttpoison

Catching HTTPoison errors with invalid port range


Encountered a situation where the url passed to get contains an invalid port

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

Seems that I am unable to catch/rescue from this scenario.


Solution

  • After digging deeper looks like the error comes from the fact that you use a port number that is bigger than the maximum accepted value.

    The ports should be in range 0..65535, if we go to source code of the function that threw the exception, we can notice the following:

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

    I cannot find the source for ?port, however I'm sure that it checks that the port is within bounds (nonnegative and smaller than 65535).

    Now the reason why you couldn't handle the error is because at some point exit() is called and process exit should be handled a little different:

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

    You encountered an error that is not handled by the HTTPoison library and is propagated to your application directly, since exit messages are propagated unless exits are trapped.

    PS: You shouldn't handle errors such as this in your application unless there is no other choice.