Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for multiple HTTP client libraries #579

Open
wants to merge 12 commits into
base: master
Choose a base branch
from

Conversation

fastjames
Copy link

In order to avoid library lock-in and allow customers to use the HTTP client library that best fits their needs, introduce the HTTPAdapter pattern with initial support for req (default), finch, and :hackney.

closes #467

@joshuap joshuap requested review from sorentwo and stympy February 13, 2025 18:15
@fastjames
Copy link
Author

The most recent test failures happen for me locally with following elixir/OTP version combos:

  • 1.15.8-otp-26 / 26.2.5.8
  • 1.15.8-otp-25 / 25.3.2.17

I also tried 1.15.8-otp-24 / 24.3.4.17 but this OTP appears to be missing some required telemetry-related capabilities so it wouldn't run at all.

I found a few references to the errors seen here in issues on erlang/otp:

I read through the docs for test_server and cowboy but I haven't yet found a way to configure which TLS versions the test server supports so that I can test the hypotheses contained in the linked erlang/otp issues.

@stympy stympy mentioned this pull request Feb 14, 2025
@sorentwo
Copy link
Collaborator

@fastjames Will you re-push to trigger a new build? The logs are gone and I can't see what the original errors were. I'm confident there is some configuration or package changes we can make to ensure Elixir v1.15 support.

@fastjames fastjames force-pushed the fastjames/feature/multi_http_client_support branch from bee10eb to 5738314 Compare February 17, 2025 18:56
@fastjames
Copy link
Author

@fastjames Will you re-push to trigger a new build? The logs are gone and I can't see what the original errors were. I'm confident there is some configuration or package changes we can make to ensure Elixir v1.15 support.

I have reordered the last 2 commits and pushed, so I think that did the trick.

@fastjames
Copy link
Author

@sorentwo Here is the downloaded log archive from the failing 1.15 test. Hopefully this contains the information we need to fix it up.
logs_34502181737.zip

Copy link
Collaborator

@sorentwo sorentwo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an impressive effort! I've left a few small suggestions, but I also think a little could be removed. Namely, the stand-alone finch adapter.

Comment on lines 124 to 130
{:ok, %{status: status} = resp} when status in 200..399 ->
{:ok, %{resp | http_adapter: http_adapter, request_url: url}}

{:ok, %{status: status} = resp} when status in 400..599 ->
{:error, %{resp | http_adapter: http_adapter, request_url: url}}

{:error, error} ->
{:error, error}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WDYT about inlining these into the case above, rather than piping into two cases?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took a shot at this and collapsing them into one case didn't feel right. It seemed to work out better as a with. That required me to flip the error handling around, so I might need to make more changes / cover more cases there.

Comment on lines +136 to +137
default_http_adapter = Application.get_env(:honeybadger, :http_adapter, @default_http_client)

case Keyword.get(opts, :http_adapter, default_http_adapter) do
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The difference between default_http_client and default_http_adapter tripped me up briefly.

Copy link
Author

@fastjames fastjames Feb 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would @default_http_client_lib be a clearer name?

Comment on lines 12 to 26
test "handles SSL" do
TestServer.start(scheme: :https)
TestServer.add("/", via: :get)

req_opts =
Keyword.put(
@req_opts,
:connect_options,
transport_opts: [cacerts: TestServer.x509_suite().cacerts],
protocols: [:http2]
)

assert {:ok, %HTTPResponse{status: 200, body: "HTTP/2"}} =
Req.request(:get, TestServer.url(), nil, [], req_opts)
end
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is testing the functionality of req, and thereby finch and mint, which seems outside the scope of what the honeybadger library should care about.

Copy link
Author

@fastjames fastjames Feb 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I can see removing this test for that reason. I don't mind it being there to keep parity with other adapter test suites (e.g. hackney) but you're right that this one isn't testing much code in the library itself.

I removed the test shown above.

fastjames and others added 9 commits February 19, 2025 10:00
Allow library consumers to choose an http client library.

Code shamelessly cribbed from [assent](https://github.com/pow-auth/assent).
Since we are setting req as the default library, include it in our test
application.
In order to speed up this iteration, defer implementation of an
`:httpc` based adapter until a later time.
Co-authored-by: Parker Selbert <[email protected]>
Co-authored-by: Parker Selbert <[email protected]>
Since `req` is built on top of `finch` it is unlikely that most
consumers would want to use `finch` directly. To reduce maintenance
surface, remove the finch adapter.
@fastjames fastjames force-pushed the fastjames/feature/multi_http_client_support branch from 16ceca6 to ac33150 Compare February 19, 2025 16:01
Since req handles response body decoding for us, move the
hackney-specific response handling code into the adapter module.
@fastjames fastjames force-pushed the fastjames/feature/multi_http_client_support branch from 5704500 to fa3dde2 Compare February 20, 2025 16:50
This happy-path test exercises code that lives outside of this library,
so its value is low (changes in this repo are unlikely to cause it to
fail).
@fastjames
Copy link
Author

Thanks for retriggering CI -- it looks like the failures on 1.16 / OTP26 are the same as before.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

HTTP client options
2 participants