Skip to content

fix: degrade change review instead of failing - #173

Closed
Waishnav wants to merge 5 commits into
mainfrom
feat/show-changes-hardening
Closed

fix: degrade change review instead of failing#173
Waishnav wants to merge 5 commits into
mainfrom
feat/show-changes-hardening

Conversation

@Waishnav

@Waishnav Waishnav commented Aug 9, 2026

Copy link
Copy Markdown
Owner

Hardens the change-review card so a bad diff can never blank the widget again.

What changed

  • parseReviewPatchFiles in the UI now guards parsing and returns an ok flag instead of throwing. Unparseable patches, external diff-driver output, and binary diffs degrade to a file-summary list with an explanatory note instead of crashing the renderer.
  • show_changes catches review failures and returns an error card (via card.error) rather than failing the whole tool call.
  • The git diff that feeds review no longer honors user-configured external diff drivers or textconv filters, so review patches are always plain unified diffs.

Why

Each of these was a real blank-widget or failed-call path in change review. The card layer should degrade gracefully; the tool call should surface the failure to the host.

No behavior change to what changes get computed — only how they render and fail.

Summary by CodeRabbit

  • New Features

    • Review results now support expandable cards with file changes, patches, and error details.
    • Multi-file reviews include collapsible diffs, binary-file summaries, and changed-file lists.
    • Review displays now show clearer file headers, grouped diffs, and summary notes.
  • Bug Fixes

    • Review failures are reported gracefully with actionable error details.
    • Empty, invalid, binary, and mixed line-ending patches are handled safely.
  • Tests

    • Expanded coverage for diff parsing, file and hunk counts, additions, deletions, renames, and file mode changes.

The review card parsed the git diff patch without guards. An unexpected
patch shape or a broken diff driver crashed card rendering and blanked
the whole review widget.

- parseReviewPatchFiles returns an ok flag instead of throwing
- multiline-diff parse failures degrade to a fallback file list using the
  card's per-file summary, with an explanatory note
- binary files render a file summary row with a hidden-diff note
- ToolResultCard gains an optional error field the card can render
show_changes threw, failing the whole tool call, when the git-backed
review could not produce a patch. The widget stayed blank at best.

Catch review failures, log them as failed tool calls, and return an
error card the widget expands to show the failure message.
git diff honors user-configured external diff drivers and textconv
filters from ~/.gitconfig, which can produce unparseable output or
launch interactive processes. Add --no-ext-diff and --no-textconv so
review patches always come back as plain unified diffs.
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 2db70676-6279-4633-ae44-56f1b5cf9c0e

📥 Commits

Reviewing files that changed from the base of the PR and between 1b4cd3f and 8a56b41.

📒 Files selected for processing (2)
  • src/ui/patch-display.test.ts
  • src/ui/patch-display.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/ui/patch-display.ts
  • src/ui/patch-display.test.ts

📝 Walkthrough

Walkthrough

The review flow now disables external diff transformations, returns structured MCP errors, parses patches without throwing, and renders binary files, parse fallbacks, expandable errors, and updated review styling.

Changes

Review diff resilience

Layer / File(s) Summary
Backend review generation and errors
src/review-checkpoints.ts, src/server.ts
Git diff disables external diff drivers and text conversion. show_changes logs review failures and returns structured error data.
Review patch parsing contract
src/ui/patch-display.ts, src/ui/patch-display.test.ts
parseReviewPatchFiles normalizes patches, tracks binary files, and reports success or failure without throwing. Tests cover standard, empty, invalid, CRLF, binary, rename, mode-change, trailing-space, and quoted-path cases.
Review card and diff rendering
src/ui/card-types.ts, src/ui/review-payload.tsx, src/ui/workspace-app.css
Review cards expand for errors. Review payloads render text diffs, binary summaries, fallback file lists, and shared file metadata with updated styling.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant show_changes
  participant reviewChanges
  participant GitDiff
  participant parseReviewPatchFiles
  participant ReviewPayload
  show_changes->>reviewChanges: request review changes
  reviewChanges->>GitDiff: compare snapshots without external transformations
  GitDiff-->>reviewChanges: patch or failure
  reviewChanges-->>show_changes: review result or structured error
  show_changes->>parseReviewPatchFiles: parse patch
  parseReviewPatchFiles-->>ReviewPayload: files, binary paths, and parse status
  ReviewPayload-->>ReviewPayload: render text, binary, fallback, or error content
Loading

Possibly related PRs

Poem

A rabbit checks each changed line,
Binary notes stay neat and fine.
Error cards open with care,
Clean diff commands guard the lair.
Patches parse through snow and rain.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: graceful degradation of change review failures.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/show-changes-hardening

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@Waishnav Waishnav changed the title feat/show changes hardening fix: degrade change review instead of failing Aug 9, 2026
@greptile-apps

greptile-apps Bot commented Aug 9, 2026

Copy link
Copy Markdown

Greptile Summary

The PR hardens show_changes by disabling external Git diff processing, returning structured error cards, and adding resilient review-patch rendering and file-summary fallbacks.

  • Adds error propagation from the show_changes server handler into expandable UI cards.
  • Centralizes guarded patch parsing and introduces summary rendering for unpreviewable and zero-hunk changes.
  • Adds parser tests and styles for static file summaries and explanatory notices.

Confidence Score: 3/5

The PR should not merge until zero-hunk metadata changes are represented accurately and patch parsing preserves boundary whitespace.

The new UI can mislabel valid mode-only or rename-only changes as binary, while full-string trimming can make the displayed final line differ from the actual Git patch.

Files Needing Attention: src/ui/review-payload.tsx, src/ui/patch-display.ts

Important Files Changed

Filename Overview
src/review-checkpoints.ts Disables external diff drivers and text conversion when generating review patches.
src/server.ts Converts show_changes failures into logged, structured error cards rather than propagating exceptions.
src/ui/patch-display.ts Adds guarded patch parsing, but whole-patch trimming can alter whitespace in the final diff line.
src/ui/review-payload.tsx Adds error and fallback rendering, but incorrectly classifies all zero-hunk changes as binary.
src/ui/card-types.ts Adds card error metadata and permits failed review cards to expand.
src/ui/patch-display.test.ts Covers valid, empty, malformed, and CRLF parser inputs but not boundary whitespace or metadata-only diffs.
src/ui/workspace-app.css Styles static fallback rows and explanatory review notices.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[show_changes] --> B[Create Git snapshot]
  B --> C[git diff with ext-diff and textconv disabled]
  C -->|failure| D[Structured error card]
  C -->|success| E[Parse review patch]
  E -->|throws| F[File-summary fallback]
  E -->|parsed files| G{Has hunks?}
  G -->|yes| H[Interactive diff preview]
  G -->|no| I[Static no-preview summary]
Loading

Reviews (1): Last reviewed commit: "fix: disable external diff drivers in re..." | Re-trigger Greptile

Comment thread src/ui/review-payload.tsx Outdated
Comment on lines +73 to +74
if (fileDiff.hunks.length === 0) {
return <BinaryFileList files={[fileDiff]} card={card} />;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Zero-hunk changes become binary

When a mode-only change, pure rename, or other metadata-only diff has no content hunks, this branch labels it as “Binary file — diff preview hidden,” causing the card to misrepresent the change and conceal its actual metadata.

Comment thread src/ui/patch-display.ts Outdated
*/
export function parseReviewPatchFiles(patch: string | undefined): ReviewPatchParse {
if (!patch) return { files: [], ok: true };
const normalized = patch.replace(/\r\n/g, "\n").trim();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Patch trimming alters final content

When the final diff line contains trailing whitespace or is itself whitespace-only, trimming the entire patch removes that content before parsing, causing the rendered preview to differ from the actual working-tree change.

Suggested change
const normalized = patch.replace(/\r\n/g, "\n").trim();
const normalized = patch.replace(/\r\n/g, "\n");

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/ui/review-payload.tsx`:
- Around line 71-75: In src/ui/review-payload.tsx lines 71-75, update the
single-file branch to classify a file as binary only when its explicit binary
metadata indicates it, not merely when fileDiff.hunks is empty; render hunkless
renames and other non-binary files as a normal static summary. Apply the same
explicit binary check in src/ui/review-payload.tsx lines 114-122 before adding
the binary-file note, preserving the existing handling for actual binary files.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 05705fd1-85e9-4517-b7c7-0cc682ac3b9e

📥 Commits

Reviewing files that changed from the base of the PR and between 1def8ce and c7a59c6.

📒 Files selected for processing (7)
  • src/review-checkpoints.ts
  • src/server.ts
  • src/ui/card-types.ts
  • src/ui/patch-display.test.ts
  • src/ui/patch-display.ts
  • src/ui/review-payload.tsx
  • src/ui/workspace-app.css

Comment thread src/ui/review-payload.tsx
Hunkless diffs are normal for renames, mode changes, and binary files, but
the review card treated every hunkless file as binary. Detect binary files
from their explicit git markers instead, render hunkless renames and mode
changes as ordinary static summaries, and stop blanking the card when a
journal-only file (e.g. an oversized diff) has no parseable hunks.

Also stop trimming patch whitespace: stripping leading and trailing
whitespace from a patch could silently drop a trailing-space change on the
final line. Only blank line runs at the patch edges are removed.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/ui/patch-display.ts`:
- Around line 190-195: Update binary path extraction in the patch parsing loop
around binaryFiles so quoted Git headers preserve the complete path, including
spaces, and match fileDiff.name in ReviewPayload. Use quote-aware Git path
parsing or parsed file metadata instead of splitting the header on spaces, and
add a regression test covering a binary filename with spaces through the
review-payload consumption path.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 59cb9d2a-471e-4c79-aaa1-f5f25b90b0d9

📥 Commits

Reviewing files that changed from the base of the PR and between c7a59c6 and 1b4cd3f.

📒 Files selected for processing (3)
  • src/ui/patch-display.test.ts
  • src/ui/patch-display.ts
  • src/ui/review-payload.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/ui/review-payload.tsx

Comment thread src/ui/patch-display.ts
The space-split fallback for binary path extraction could record a
fragment of a quoted header as the file name. Git diff headers already
carry the new path after the 'b/' prefix, quoted when the path contains
special characters, so the header match alone is sufficient and test
coverage now locks in paths containing spaces, both plain and quoted.
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.

1 participant