fix(mint): standardize adapter_payload shape on disconnect#511
Merged
sleipnir merged 2 commits intoelixir-grpc:masterfrom Mar 23, 2026
Merged
Conversation
57650d6 to
3e88ee2
Compare
… BadMapError
The Mint adapter set `adapter_payload: nil` on disconnect, while Gun kept
`adapter_payload: %{conn_pid: nil}`. This inconsistency caused
`GRPC.Stub.call/5` to crash with a BadMapError when accessing
`ch.adapter_payload.conn_pid` after a Mint disconnect.
- Mint.disconnect/1 now returns `%{conn_pid: nil}` matching Gun's convention
- Mint's nil guards (send_request/3, send_headers/2) match `%{conn_pid: nil}`
- Stub.call/5 uses pattern matching guard on adapter_payload as defense
- Added disconnect/1 tests to both adapter test files
Made-with: Cursor
3e88ee2 to
6723431
Compare
sleipnir
approved these changes
Mar 23, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The Mint adapter sets
adapter_payload: nilafterdisconnect/1, while the Gun adapter setsadapter_payload: %{conn_pid: nil}. This inconsistency causes a crash inGRPC.Stub.call/5, which accessesch.adapter_payload.conn_pidwithout guarding against a niladapter_payload:When using the Mint adapter, any RPC call made after disconnect crashes with:
BadMapError: expected a map, got: nil— whenadapter_payloadisniland.conn_pidis accessed on it.ArgumentError: Can't perform a request without a connection process— when the Mint adapter's own guard catches the nil first.conn_pid: nilandGenServer.callis attempted on it.The Gun adapter never hits this path because it preserves the map shape
%{conn_pid: nil}on disconnect.Root cause
In
GRPC.Client.Adapters.Mint.disconnect/1:vs.
GRPC.Client.Adapters.Gun.disconnect/1:Fix
1. Standardize Mint's
disconnect/1to match Gun's conventionadapter_payloadnow stays as%{conn_pid: nil}after disconnect instead of being set tonil:2. Update Mint's guard clauses
send_request/3andsend_headers/2now match on%{conn_pid: nil}instead ofadapter_payload: nil:3. Defense-in-depth in
Stub.call/5Added a pattern matching guard on the
pick_channelresult so that only channels with a valid mapadapter_payloadenter theProcess.alive?path. Channels withnilor missingadapter_payloadfall through to the catch-all, which logs a warning and falls back to the stream's channel:Files changed
grpc_client/lib/grpc/client/adapters/mint.ex%{conn_pid: nil}on disconnect; update guard clausesgrpc_client/lib/grpc/stub.exadapter_payloadto preventBadMapErrorgrpc_client/test/grpc/adapters/gun_test.exsdisconnect/1tests (shape + idempotency)grpc_client/test/grpc/adapters/mint_test.exsdisconnect/1tests (shape + idempotency + error on nil conn_pid)Test plan
mix test test/grpc/adapters/gun_test.exs— disconnect keeps%{conn_pid: nil}mix test test/grpc/adapters/mint_test.exs— disconnect keeps%{conn_pid: nil}, raisesArgumentErroron RPCmix test— full suite passes (219 tests, 0 failures)