Closed adamcstephens closed 3 weeks ago
Hi,
I got the same error. I had to rollback to our custom Req implemenation. Also the way it's implemented, you need to have :hackney
and Req
in your project besides the dependencies being declared as optional.
Otherwise you get this Elixir warning at compilation:
==> ex_aws
Compiling 28 files (.ex)
warning: Req.request/1 is undefined (module Req is not available or is yet to be defined)
│
22 │ |> Req.request()
│ ~
│
└─ (ex_aws 2.5.5) lib/ex_aws/request/req.ex:22:12: ExAws.Request.Req.request/5
warning: :hackney.request/5 is undefined (module :hackney is not available or is yet to be defined)
│
21 │ case :hackney.request(method, url, headers, body, opts) do
│ ~
│
└─ (ex_aws 2.5.5) lib/ex_aws/request/hackney.ex:21:19: ExAws.Request.Hackney.request/5
Generated ex_aws app
this is the culprit: https://github.com/ex-aws/ex_aws/blob/821722c795c714a10ef74399054855ed6c02b8c3/lib/ex_aws/instance_meta.ex#L107
=> a default http option from hackney, that does not exist in req, and that cannot be change by setting something in the config
we might be able to work around this by convincing req to accept this option: https://hexdocs.pm/req/Req.Request.html#register_options/2 (somewhere in ExAws.Request.Req ? or maybe even add a custom Req step that transforms hackney options to req options?)
I'm too tired to investigate more tonight, I hope that someone else will have fixed the issue by tomorrow morning :-)
my current workaround:
# config.exs
config :ex_aws,
access_key_id: [:instance_role],
secret_access_key: [:instance_role],
http_client: MyHttpClient
# my_http_client.ex
# copied from https://github.com/ex-aws/ex_aws/blob/main/lib/ex_aws/request/req.ex
defmodule MyHttpClient do
@behaviour ExAws.Request.HttpClient
@moduledoc """
Configuration for `m:Req`.
Options can be set for `m:Req` with the following config:
config :ex_aws, :req_opts,
receive_timeout: 30_000
The default config handles setting the above.
"""
@default_opts [receive_timeout: 30_000]
@impl true
def request(method, url, body \\ "", headers \\ [], http_opts \\ []) do
[method: method, url: url, body: body, headers: headers, decode_body: false]
|> Keyword.merge(Application.get_env(:ex_aws, :req_opts, @default_opts))
|> Keyword.merge(Keyword.delete(http_opts, :follow_redirect)) # the temporary fix!
|> Req.request()
|> case do
{:ok, %{status: status, headers: headers, body: body}} ->
{:ok, %{status_code: status, headers: headers, body: body}}
{:error, reason} ->
{:error, %{reason: reason}}
end
end
end
Environment
Elixir 1.17.2 (compiled with Erlang/OTP 27)
mix deps | grep hackney
Current behavior
Attempting to use the Req backend fails as
:follow_redirect
is not an http option. This error is from Broadway SQS.Expected behavior
Expect to successfully connect to SQS.