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

@WaishnavWaishnav 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

coderabbitaiBot 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 nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring 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 nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly and concisely describes the main change: graceful degradation of change review failures.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck 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.

@WaishnavWaishnav changed the title feat/show changes hardeningfix: degrade change review instead of failingAug 9, 2026
@greptile-apps

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

FilenameOverview
src/review-checkpoints.tsDisables external diff drivers and text conversion when generating review patches.
src/server.tsConverts show_changes failures into logged, structured error cards rather than propagating exceptions.
src/ui/patch-display.tsAdds guarded patch parsing, but whole-patch trimming can alter whitespace in the final diff line.
src/ui/review-payload.tsxAdds error and fallback rendering, but incorrectly classifies all zero-hunk changes as binary.
src/ui/card-types.tsAdds card error metadata and permits failed review cards to expand.
src/ui/patch-display.test.tsCovers valid, empty, malformed, and CRLF parser inputs but not boundary whitespace or metadata-only diffs.
src/ui/workspace-app.cssStyles 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 threadsrc/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.

P1Zero-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 threadsrc/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.

P1Patch 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
constnormalized=patch.replace(/\r\n/g,"\n").trim();
constnormalized=patch.replace(/\r\n/g,"\n");

@coderabbitaicoderabbitaiBot 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 threadsrc/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.

@coderabbitaicoderabbitaiBot 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 threadsrc/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 freeto 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

@Waishnav