Skip to content

fix: keep the Msg/Level/State header on errors sent to stderr with -r - #811

Closed
Raymondriter wants to merge 1 commit into
microsoft:mainfrom
Raymondriter:fix/stderr-error-header
Closed

Raymondriter wants to merge 1 commit into
microsoft:mainfrom
Raymondriter:fix/stderr-error-header

Conversation

@Raymondriter

Copy link
Copy Markdown

Fixes #794

Problem

With -r, runQuery passed only e.Message to the PrintError hook. Because the hook returns true, Formatter.AddError was skipped, and that's where the Msg N, Level N, State N, Server S, Line N header is built. Errors on stderr lost the error number and line. ODBC sqlcmd prints the same text with -r and only changes the destination.

Fix

  • Move the header formatting from AddError into errorHeader(e mssql.Error). The localized format strings are unchanged, so existing translations still apply.
  • Pass errorHeader(e) + e.Message to PrintError, so a host that redirects errors gets the text the default output would show.
  • The PrintError signature is unchanged. I documented on the field that msg includes the header for server errors.

Tests

  • New TestPrintErrorIncludesErrorHeader runs RAISERROR (N'Testing!', 11, 1) with a redirecting hook. It asserts the hook receives Msg 50000, Level 11, State 1, Server ..., Line 1 followed by the message, and that nothing reaches the default output. On main the hook receives only Testing!.

  • Full suite against a local SQL Server 2022 container: the same results as main. The only failures are the environment-dependent install/ADS/editor tests.

  • End to end with the repro from the issue (sqlcmd -r -b -i repro.sql), stderr now reads:

    Msg 207, Level 16, State 1, Server <host>, Line 1
    Invalid column name 'id'.
    

    This matches the output without -r.

Not addressed here: the issue's additional observation that -b stops after the first error of a batch. It's a separate behaviour change, and I can follow up in its own PR.

🤖 Generated with Claude Code

With -r, runQuery handed the PrintError hook only e.Message, and the
hook's `true` return skipped Formatter.AddError, which is where the
"Msg N, Level N, State N, Server S, Line N" header is built. Errors on
stderr therefore lost the error number and line, unlike ODBC sqlcmd,
where -r only changes the destination.

Move the header formatting into errorHeader() and pass header+message
to PrintError, so a redirecting host gets the same text the default
output shows. The PrintError signature is unchanged.

Fixes microsoft#794

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings September 14, 2026 16:55

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Redirected errors omit the mssql: prefix when -r is combined with -j.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Fixes redirected SQL Server errors so -r output retains the standard diagnostic header.

Changes:

  • Centralizes localized error-header formatting.
  • Includes headers in redirected error messages.
  • Adds integration coverage and documents the PrintError contract.
File summaries
File Summary
pkg/sqlcmd/sqlcmd.go Updates redirected error handling and documentation.
pkg/sqlcmd/sqlcmd_test.go Tests redirected error headers.
pkg/sqlcmd/format.go Centralizes server error header formatting.
Review details
  • Files reviewed: 3/3 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread pkg/sqlcmd/sqlcmd.go
switch e := m.Error.(type) {
case mssql.Error:
if !s.PrintError(e.Message, e.Class) {
if !s.PrintError(errorHeader(e)+e.Message, e.Class) {
@Raymondriter

Copy link
Copy Markdown
Author

Withdrawing this for now. The root cause and fix are described above in case they're useful to anyone picking up #794.

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.

-r discards the "Msg N, Level N, State N" error header — errors on stderr lose message number and line info

2 participants