Surface MSSQL token detail when the connection closes#185
Open
kevinkoltz wants to merge 2 commits into
Open
Conversation
SQL Server frequently sends an error token immediately before closing the connection (login failure, fatal severity, kill by DBA). The token was parsed and surfaced to the caller of the failing statement, then dropped when the socket closed — the disconnect error reported only "Connection closed." / "tcp closed" / "Connection failed to receive packet due :closed", forcing operators to dig through server-side logs to learn the actual reason. This change carries the most recent token on the protocol state (`last_mssql_error`, captured in the existing `msg_error` handler and cleared on `checkout/1`) and uses it when building the disconnect error at the five masking sites in `protocol.ex` (`ping/1`, the two `handle_info` clauses for `:tcp_closed` / `:ssl_closed` / `:tcp_error` / `:ssl_error`, the `flush/1` receive, and the `msg_recv/1` socket read-error path). The disconnect-vs-stop return semantics are unchanged, so DBConnection's pool-managed reconnect continues to work exactly as before. `Tds.Error.message/1` gains a head that combines `:message` and `:mssql` when both are populated, so existing callers that pattern-match on either field individually keep working while connection-close errors now surface the underlying server reason. The `error_details` typespec is broadened to reflect the full set of fields the token stream decodes in `Tokens.decode_error/2`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
GitHub Actions runners now ship with a pre-existing /etc/apt/sources.list.d/microsoft-prod.list that references signed-by=/usr/share/keyrings/microsoft-prod.gpg. The workflow added a second source for the same repository signed by a key in /etc/apt/trusted.gpg.d, which apt rejected as a conflicting signed-by configuration (exit code 100 from apt-get update). Remove the runner-provided list and install the key into the expected keyrings location with an explicit signed-by entry to match. Same fix adopted by elixir-ecto#184 to unblock CI on PRs against master. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.
SQL Server frequently sends an error token immediately before closing the connection (login failure, fatal severity, kill by DBA). The token was parsed and surfaced to the caller of the failing statement, then dropped when the socket closed — the disconnect error reported only "Connection closed." / "tcp closed" / "Connection failed to receive packet due :closed", forcing operators to dig through server-side logs to learn the actual reason.
This change carries the most recent token on the protocol state (
last_mssql_error, captured in the existingmsg_errorhandler and cleared oncheckout/1) and uses it when building the disconnect error at the five masking sites inprotocol.ex(ping/1, the twohandle_infoclauses for:tcp_closed/:ssl_closed/:tcp_error/:ssl_error, theflush/1receive, and themsg_recv/1socket read-error path). The disconnect-vs-stop return semantics are unchanged, so DBConnection's pool-managed reconnect continues to work exactly as before.Tds.Error.message/1gains a head that combines:messageand:mssqlwhen both are populated, so existing callers that pattern-match on either field individually keep working while connection-close errors now surface the underlying server reason. Theerror_detailstypespec is broadened to reflect the full set of fields the token stream decodes inTokens.decode_error/2.