Middleware.PathParams :erlang.binary_to_existing_atom error for google APIs
I'm migrating from another lib to Tesla and I found an issue while trying to use got integrated this API.
This is the error that I got:
** (ArgumentError) argument error
code: @middleware.call(%Env{url: "/v1/brands/:brand_id/agents/:agent_id:requestLaunch", opts: opts}, [], nil)
stacktrace:
:erlang.binary_to_existing_atom("requestLaunch", :utf8)
(tesla) lib/tesla/middleware/path_params.ex:39: anonymous fn/3 in Tesla.Middleware.PathParams.build_url/2
(elixir) lib/regex.ex:731: Regex.apply_list/5
(elixir) lib/regex.ex:732: Regex.apply_list/5
(elixir) lib/regex.ex:726: Regex.apply_list/5
(elixir) lib/regex.ex:668: Regex.do_replace/4
(tesla) lib/tesla/middleware/path_params.ex:31: Tesla.Middleware.PathParams.call/3
test/tesla/middleware/path_params_test.exs:91: (test)
The problem is that the path for this API request is using a colon to indicate one action in the path /v1/brands/__BRAND_ID__/agents/__AGENT_ID__:requestLaunch (see doc).
I know that I could just pass the ":requestLaunch" as a path param as well:
path = "/v1/brands/:brand_id/agents/:agent_id:requestLaunch"
path_params = [
agent_id: ...,
brand_id: ...,
requestLaunch: ":requestLaunch"
]
...
But it is very odd/ugly, and I think we should fix it on the middleware.
I have the following suggestion that we could:
1 - Add a rescue clause
Since we are using the String.to_existing_atom/1 function on lib/tesla/middleware/path_params.ex:39 we could rescue it if it fails.
defmodule Tesla.Middleware.PathParams do
...
defp build_url(url, params) do
Regex.replace(@rx, url, fn match, key ->
try do
to_string(params[String.to_existing_atom(key)] || match)
rescue
ArgumentError -> match
end
end)
end
end
I'm unsure if we will want it not to throw an error if the param does not exist.
2 - Regex change
We can also change the regex to only fetch params that come after a slash / (it would imply on add back the slash again while we are doing the replacement).
defmodule Tesla.Middleware.PathParams do
...
@rx ~r/\/:([a-zA-Z]{1}[\w_]*)/
...
defp build_url(url, params) do
Regex.replace(@rx, url, fn match, key ->
"/" <> to_string(params[String.to_existing_atom(key)] || match)
end)
end
end
What do you think? I can work on opening a pull request for that as well. for now, I'm passing as a param 😬.
Middleware.PathParams :erlang.binary_to_existing_atom error for google APIs
I'm migrating from another lib to Tesla and I found an issue while trying to use got integrated this API.
This is the error that I got:
The problem is that the path for this API request is using a colon to indicate one action in the path
/v1/brands/__BRAND_ID__/agents/__AGENT_ID__:requestLaunch(see doc).I know that I could just pass the ":requestLaunch" as a path param as well:
But it is very odd/ugly, and I think we should fix it on the middleware.
I have the following suggestion that we could:
1 - Add a rescue clause
Since we are using the
String.to_existing_atom/1function onlib/tesla/middleware/path_params.ex:39we could rescue it if it fails.I'm unsure if we will want it not to throw an error if the param does not exist.
2 - Regex change
We can also change the regex to only fetch params that come after a slash
/(it would imply on add back the slash again while we are doing the replacement).What do you think? I can work on opening a pull request for that as well. for now, I'm passing as a param 😬.