HTTPoison sending :EXIT message after request?

I have been using HTTPoison for my requests for quite some time.
Requests are abstracted in a request module (status code validation, payload (de)serialization, tracing, …).

Over the weekend I added a new request to my project, and whenever the request was done, the calling process crashed afterwards. The request itself is succesful. If I remove the request (and instead construct a manual HTTPoison.Response), everything stays alive as intended.

The reason was a missing handle_info to catch

handle_info({:EXIT, pid, :normal}, state)

I have added the handle_info to prevent the crash, but I do not understand why this happens. I have not run into this before, so I wonder what causes this behaviour.

{:EXIT, pid, :normal} is the shape of message you’d get if the process that receives it is trapping exits and started a Task that completes normally.

It’s hard to speculate further about exactly what’s going wrong without seeing code.

See also https://github.com/benoitc/hackney/issues/464 although that’s a totally different message.

Sounds about right, the process the request is made from does trap exits.
So I guess HTTPoison spins up a process in the background and links it to the caller?

There’s some :poolboy plumbing under the hood, but I’m not sure the library is the right place to look - you mentioned that this ONLY happens for the request that you’ve just added. I’d expect a library issue to affect all requests equally (even if intermittently like #464 above), unless there’s something special about the new request.

I am even doing some more requests from the same GenServer.
However, those requests happen during init (to collect data or crash when no data can be collected) and those requests are done before trapping exits is enabled at a later point in init().

Although I think the :EXIT messages would be collected in the inbox until after init is done, so even if trapping exits is enabled after the requests, I should see the same behaviour?

If a linked process exits when exits aren’t being trapped, the GenServer will also exit immediately with the same reason.