Skip to content

Better error handling: show GitVersion output when JSON parsing fails#2029

Merged
arturcic merged 5 commits intomainfrom
copilot/fix-azure-error-handling
Apr 7, 2026
Merged

Better error handling: show GitVersion output when JSON parsing fails#2029
arturcic merged 5 commits intomainfrom
copilot/fix-azure-error-handling

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 7, 2026

When GitVersion exits with code 0 but produces non-JSON output (e.g., due to a configuration error), the task reported a generic GitVersion output is not valid JSON error with no actionable detail — the actual GitVersion output was silently discarded.

Changes

  • runner.ts (gitversion)processGitVersionOutput: when gitVersionOutput === null, the full stdout is logged at info level first (keeping it visible in the build log), then the last 20 lines are embedded in the error message with a truncation note when the output is longer:

    GitVersion output is not valid JSON (showing last 20 of N lines)
    INFO [...] Working directory: ...
    ERROR [...] Some actual GitVersion error here
    

    Falls back to 'GitVersion output is not valid JSON, see output details' when stdout is empty.

  • runner.ts (gitversion)handleOutputError: removed the direct setFailed call; instead sets stderr on the returned ExecResult and delegates failure reporting to safeExecute. Previously, safeExecute would overwrite the meaningful error with setFailed(undefined) after handleOutputError had already set the right message.

  • runner.ts (common)safeExecute: fixed the non-zero exit branch to check result.stderr first, then fall back to result.error.message, rather than unconditionally casting result.stderr as string (which produced ##[error]undefined in the logs).

  • runner.spec.ts (gitversion) — added tests for processGitVersionOutput covering: short output (full snippet included in error), long output (truncated to last 20 lines with line-count note), and empty output (fallback message).

Copilot AI linked an issue Apr 7, 2026 that may be closed by this pull request
2 tasks
Copilot AI changed the title [WIP] Fix error handling in Azure GitVersion task Better error handling: show GitVersion output when JSON parsing fails Apr 7, 2026
Copilot AI requested a review from arturcic April 7, 2026 13:14
@arturcic arturcic marked this pull request as ready for review April 7, 2026 13:37
Copilot AI review requested due to automatic review settings April 7, 2026 13:37
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Improves diagnostics when GitVersion returns non-JSON output despite exiting successfully, ensuring the underlying stdout is surfaced and failures are reported consistently.

Changes:

  • Include GitVersion stdout in the “output is not valid JSON” error path (with an empty-stdout fallback message).
  • Adjust GitVersion’s JSON-parse failure handling to return an ExecResult with stderr (instead of calling setFailed directly) so safeExecute reports the right message.
  • Fix safeExecute failure reporting to prefer result.stderr, then fall back to result.error.message to avoid ##[error]undefined.

Reviewed changes

Copilot reviewed 2 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/tools/gitversion/runner.ts Surface non-JSON stdout in the error and return stderr via ExecResult for consistent failure reporting.
src/tools/common/runner.ts Improve failure logging/setFailed behavior by handling missing stderr safely.
package-lock.json Lockfile update (removes nested TypeScript entry).
dist/tools/libs/tools.mjs Built output reflecting safeExecute behavior changes.
dist/tools/libs/tools.mjs.map Source map update for the common runner changes.
dist/tools/libs/gitversion.mjs Built output reflecting GitVersion runner error-message changes.
dist/tools/libs/gitversion.mjs.map Source map update for GitVersion runner changes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +70 to +74
const gitVersionStdout = result.stdout?.trim()
const message = gitVersionStdout
? `GitVersion output is not valid JSON\n${gitVersionStdout}`
: 'GitVersion output is not valid JSON, see output details'
return this.handleOutputError(message)
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

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

gitVersionStdout is appended verbatim into the failure message. Since exec allows up to a 10MB buffer (see src/agents/common/build-agent.ts:257), this can create extremely large error messages (noisy logs and potential truncation/command-size limits in CI log commands). Consider truncating the embedded stdout (e.g., last N lines / first N chars) and indicating that it was truncated, while still keeping the full stdout available via normal log output when possible.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@copilot apply changes based on this feedback

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed in 27c05f4. processGitVersionOutput now logs the full stdout at info level (so it remains visible in the build log), then embeds only the last 20 lines of trimmed output in the error message. When the output is longer than 20 lines, a note like (showing last 20 of N lines) is appended to the header. Three new tests cover: short output (full snippet included), long output (truncated with line-count note), and empty output (fallback message).

Comment on lines 69 to 75
if (gitVersionOutput === null) {
return this.handleOutputError('GitVersion output is not valid JSON, see output details')
const gitVersionStdout = result.stdout?.trim()
const message = gitVersionStdout
? `GitVersion output is not valid JSON\n${gitVersionStdout}`
: 'GitVersion output is not valid JSON, see output details'
return this.handleOutputError(message)
}
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

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

There are existing GitVersion runner tests (src/tests/tools/gitversion/runner.spec.ts), but none cover the updated behavior when JSON extraction returns null. Please add/adjust a test to assert that processGitVersionOutput returns a non-zero ExecResult whose stderr includes the original stdout (and uses the fallback message when stdout is empty), so the new error detail remains stable.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@copilot apply changes based on this feedback

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

These tests were already added in 27c05f4 as part of addressing the previous comment. The three new tests in testOnAgent cover:

  • Short stdout: processGitVersionOutput returns code: -1 with stderr containing the stdout snippet
  • Long stdout (30 lines): truncated to last 20 lines with showing last 20 of 30 lines note
  • Empty stdout: fallback message 'GitVersion output is not valid JSON, see output details'

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 8 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +76 to +77
const { truncated, wasTruncated, totalLines } = this.truncateOutput(gitVersionStdout)
const truncationNote = wasTruncated ? ` (showing last 20 of ${totalLines} lines)` : ''
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

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

The truncation note hardcodes last 20 while truncateOutput accepts maxLines. To avoid the message drifting if maxLines is ever changed, consider defining a maxLines const, passing it into truncateOutput, and using it in the note instead of a literal.

Suggested change
const { truncated, wasTruncated, totalLines } = this.truncateOutput(gitVersionStdout)
const truncationNote = wasTruncated ? ` (showing last 20 of ${totalLines} lines)` : ''
const maxLines = 20
const { truncated, wasTruncated, totalLines } = this.truncateOutput(gitVersionStdout, maxLines)
const truncationNote = wasTruncated ? ` (showing last ${maxLines} of ${totalLines} lines)` : ''

Copilot uses AI. Check for mistakes.
Comment on lines +94 to +96
const lines = output.split('\n')
if (lines.length <= maxLines) {
return { truncated: output, wasTruncated: false, totalLines: lines.length }
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

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

truncateOutput splits only on \n. If the tool emits CRLF (\r\n), the truncated snippet will retain trailing \r characters, which can make the embedded error snippet look messy. Consider splitting with /\r?\n/ (and joining with \n) to normalize line endings.

Suggested change
const lines = output.split('\n')
if (lines.length <= maxLines) {
return { truncated: output, wasTruncated: false, totalLines: lines.length }
const lines = output.split(/\r?\n/)
if (lines.length <= maxLines) {
return { truncated: lines.join('\n'), wasTruncated: false, totalLines: lines.length }

Copilot uses AI. Check for mistakes.
@arturcic
Copy link
Copy Markdown
Member

arturcic commented Apr 7, 2026

@copilot apply changes based on the comments in this thread

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 7, 2026

@copilot apply changes based on the comments in this thread

Applied both suggestions in c9a6d00:

  • Extracted maxLines = 20 as a const and use it in the truncation note instead of the hardcoded literal
  • truncateOutput now splits on /\r?\n/ and joins with \n to normalize CRLF line endings

@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud bot commented Apr 7, 2026

@arturcic arturcic merged commit 7042d12 into main Apr 7, 2026
20 checks passed
@arturcic arturcic deleted the copilot/fix-azure-error-handling branch April 7, 2026 14:36
@mergify
Copy link
Copy Markdown
Contributor

mergify bot commented Apr 7, 2026

Thank you @Copilot for your contribution!

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.

[ISSUE]: Better error handling in Azure

3 participants