Skip to content

fix: report the close frame as the disconnect reason - #92

Merged
nmbrone merged 1 commit into
mainfrom
fix/close-reason
Sep 4, 2026
Merged

fix: report the close frame as the disconnect reason#92
nmbrone merged 1 commit into
mainfrom
fix/close-reason

Conversation

@nmbrone

@nmbrone nmbrone commented Sep 3, 2026

Copy link
Copy Markdown
Owner

The close handshake is handled internally, so the code and reason the server sent never reached the client — handle_disconnect/3 only saw the transport error from the socket closing afterwards, which made application close codes unreachable.

It now reports the close frame instead, whichever side started the handshake. Also cancels a previous close timer when a new handshake starts, and adds a :close_timeout option (default 5000).

handle_disconnect/3 receives {:close, code, reason} where it previously received %Mint.TransportError{reason: :closed}.

@nmbrone nmbrone changed the title fix!: report the close frame as the disconnect reason fix: report the close frame as the disconnect reason Sep 3, 2026
@nmbrone
nmbrone force-pushed the fix/close-reason branch 6 times, most recently from 06f3a93 to 62b679d Compare September 3, 2026 17:48
@nmbrone
nmbrone force-pushed the fix/close-reason branch 4 times, most recently from 8f1d8f8 to 6bbd442 Compare September 4, 2026 07:53
@nmbrone
nmbrone requested a review from vshev4enko September 4, 2026 08:03
The close handshake is handled internally, so the code and reason the server
sent were dropped: `handle_disconnect/3` only ever saw the transport error from
the socket shutting down afterwards, leaving application close codes such as
1008 or the 4000 range unreachable.

Remember the frame when the handshake starts and report it instead, falling
back to the Mint error when there was no handshake. The frame is cleared on
close so a code cannot leak into the next connection's disconnect.

`handle_disconnect/3` now receives `{:close, code, reason}` where it previously
received `%Mint.TransportError{reason: :closed}` for a connection closed through
the handshake by either side.

fix: cancel the previous close timer when starting a handshake

`send_close/2` overwrote `close_timer` without cancelling it, and `close/1` only
cancels the timer it can see. Two handshakes inside the timeout window left the
first timer armed, so it fired after the connection had been closed and
re-established, and tore down the healthy connection.

feat: add the `:close_timeout` option

How long to wait for the server to close the connection once a close handshake
has started, in milliseconds, defaulting to the 5000 that used to be hardcoded.
Also makes the timeout testable: the new test suspends the server so the
handshake is never answered.
@nmbrone
nmbrone merged commit c2fb6f6 into main Sep 4, 2026
4 checks passed
@nmbrone
nmbrone deleted the fix/close-reason branch September 4, 2026 08:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants