Skip to content

[BUG] [Elixir] Missing body in POST or PUT cause crash (Simple Fix!) #5403

@madasebrof

Description

@madasebrof

This is a simple bug with a simple fix.

If an endpoint uses a POST or a PUT but doesn't require anything in the BODY tag, the underlying HTTP client on Elixir (Erlang) :httpc will bomb.

E.g. generated code that looks like this:

@spec iserver_reauthenticate_post(Tesla.Env.client, keyword()) :: {:ok, ClientPortalWebAPI.Model.AuthStatus.t} | {:error, Tesla.Env.t}
def iserver_reauthenticate_post(connection, _opts \\ []) do
  %{}
  |> method(:post)
  |> url("/iserver/reauthenticate")
  |> Enum.into([])
  |> (&Connection.request(connection, &1)).()
  |> evaluate_response([
    { 200, %ClientPortalWebAPI.Model.AuthStatus{}}
  ])
end

will cause a crash like this:

** (FunctionClauseError) no function clause matching in :httpc.request/5    
    
    The following arguments were given to :httpc.request/5:
    
        # 1
        :post
    
        # 2
        {'http://192.168.1.137:5000/v1/portal/iserver/reauthenticate',
         [{'user-agent', 'Elixir'}]}
    
        # 3
        [autoredirect: false]
    
        # 4
        []
    
        # 5
        :default
    
(inets) httpc.erl:149: :httpc.request/5
(app) lib/client_portal_web_api/deps/tesla/lib/tesla/adapter/httpc.ex:52: Tesla.Adapter.Httpc.request/2
(app) lib/client_portal_web_api/deps/tesla/lib/tesla/adapter/httpc.ex:22: Tesla.Adapter.Httpc.call/2
(app) lib/client_portal_web_api/lib/client_portal_web_api/api/session.ex:58: ClientPortalWebAPI.Api.Session.iserver_reauthenticate_post/2

Becasue :httpc doesn't allow a missing body for a POST or PUT.

The simple fix is to always include an empty body if the spec doesn't require anything, e.g. change:

|> Enum.into([])

to:

|> Enum.into([body: %{}])

for a missing body for a POST or PUT.

@spec iserver_reauthenticate_post(Tesla.Env.client, keyword()) :: {:ok, ClientPortalWebAPI.Model.AuthStatus.t} | {:error, Tesla.Env.t}
def iserver_reauthenticate_post(connection, _opts \\ []) do
  %{}
  |> method(:post)
  |> url("/iserver/reauthenticate")
  |> Enum.into([body: %{}])
  |> (&Connection.request(connection, &1)).()
  |> evaluate_response([
    { 200, %ClientPortalWebAPI.Model.AuthStatus{}}
  ])
end

PS Thanks for all the work on this! Saved a ton of time!!!

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions