appcues / mojito

An easy-to-use Elixir HTTP client, built on the low-level Mint library.
https://hexdocs.pm/mojito/Mojito.html
MIT License
349 stars 34 forks source link

Mojito returns `{:error, %Mojito.Error{message: nil, reason: :timeout}}` while HTTPoison or cURL works #86

Closed alexandremcosta closed 2 years ago

alexandremcosta commented 3 years ago

Mojito returns {:error, %Mojito.Error{message: nil, reason: :timeout}} intermittently. It's rare, but it happens in our production system and it will be impossible to keep using Mojito with this problem.

I used this to reproduce. It takes sometime, but eventually you will see it:

  defmodule Bug do
    def reproduce(amount \\ 10, http_client \\ Mojito) do
      Enum.each(1..amount, fn i ->
        IO.write("#{i}/#{amount}\t\r")
        http_client |> request() |> handle_response()
      end)
    end

    defp request(http_client) do
      http_client.get("https://jsonplaceholder.typicode.com/todos/1")
    end

    defp handle_response({:ok, %{status_code: 200}}), do: :ok

    defp handle_response(response) do
      IO.inspect(response, label: :error)
      raise(RuntimeError)
    end
  end

  Bug.reproduce(10000)

It never happens on Bug.reproduce(10000, HTTPoison). I'm on 0.7.7 and my config is default.

DunyaKokoschka commented 3 years ago

are you using the same timeout settings for mojito and httpoison? the server is http2 so maybe it is a http2 issue. you can disable http2 in mojito.

andyleclair commented 3 years ago

@alexandremcosta Hi, thank you for the bug report! I just tried running this code against the latest master (Elixir 1.12.1 and Erlang 24.0.2) and I didn't see it fail. Can you try to reproduce it locally again with master? I'd love some more information if maybe there's a version incompatibility or something

andyleclair commented 3 years ago

Sorry, I should have tried other inputs before I said anything! I wasn't able to reproduce that error, but when I called Bug.reproduce(100_000) eventually I got

error: {:error,
 %Mojito.Error{
   message: nil,
   reason: %Mint.HTTPError{module: Mint.HTTP2, reason: :closed_for_writing}
 }}

Which does seem like something we should resolve!

strzibny commented 3 years ago

I think we hit this very issue at work. It got so bad we had to switch to HTTPoison, at least for now. Unfortunately I don't know why it happens.

ntenczar commented 2 years ago

Hi! This project is now deprecated:

We recommend that you use Finch which is also built on Mint. The creator of Finch has an excellent writeup here describing the problems with Mojito, and as a result we use Finch internally at Appcues now.