Skip to content

[FIX] Add error fallback for PDF viewer when document fails to load#1781

Merged
gaya3-zipstack merged 6 commits intomainfrom
fix/pdf-viewer-error-fallback
Mar 9, 2026
Merged

[FIX] Add error fallback for PDF viewer when document fails to load#1781
gaya3-zipstack merged 6 commits intomainfrom
fix/pdf-viewer-error-fallback

Conversation

@vishnuszipstack
Copy link
Contributor

@vishnuszipstack vishnuszipstack commented Feb 6, 2026

What

  • Added error handling fallback to the PdfViewer component that displays a user-friendly error message with a Retry button when a PDF fails to load (corrupted file, network error, invalid URL)
  • Added empty state handling when no fileUrl is provided, showing a "No PDF Available" warning instead of a blank screen
  • Added CSS styles for the error fallback UI

Why

  • Previously, if a PDF failed to load in the HITL review screen due to a missing/invalid URL or corrupted file, the viewer would render a blank screen with no feedback to the user
  • Users had no indication of what went wrong or how to recover

How

  • Used the renderError prop of @react-pdf-viewer/core Viewer component to catch PDF load failures and render a custom error UI using Ant Design's Result component
  • Added a retryKey state to force the Viewer to re-mount when the Retry button is clicked
  • Added an early return guard when fileUrl is falsy to show the "No PDF Available" state
  • Added an optional onError callback prop so parent components can be notified of PDF load errors

Can this PR break any existing features. If yes, please list possible items. If no, please explain why.

  • No — this only adds error handling for failure cases. Normal PDF loading behavior is unchanged. The onError prop is optional and does not affect existing usage.

Database Migrations

  • None

Env Config

  • None

Relevant Docs

  • None

Related Issues or PRs

  • None

Dependencies Versions

  • No new dependencies. Uses existing antd and @ant-design/icons packages.

Notes on Testing

  • Open HITL review screen with a valid PDF document — verify it loads normally
  • Simulate a broken/invalid PDF URL — verify the "Failed to Load PDF" error message appears with a Retry button
  • Click the Retry button — verify the viewer attempts to reload the PDF
  • Test with an empty/null file URL — verify the "No PDF Available" warning message appears

Screenshots

  • N/A

Checklist

I have read and understood the Contribution Guidelines.

Previously, if a PDF failed to load due to an invalid/unavailable URL or
corrupted file, the viewer would render a blank screen with no feedback.
This adds a user-friendly error fallback with a retry option, and handles
the case when no file URL is provided.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 6, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Summary by CodeRabbit

  • New Features

    • Enhanced PDF viewer with improved error handling and a visible error screen when loading fails
    • Added retry functionality to recover from PDF loading failures
    • Better messaging and empty-state UI when no PDF is available
  • Style

    • Polished error-state visual design for clearer typography, spacing, and layout

Walkthrough

Adds error-state styles and retry/error-handling to the PDF viewer: new CSS for error presentation; PdfViewer gains loadError and retryKey state, an onError prop, a PdfLoadError render path using Ant Design Result with a retry that remounts the viewer, and guards for empty file URL.

Changes

Cohort / File(s) Summary
PDF Viewer UI & Logic
frontend/src/components/custom-tools/pdf-viewer/PdfViewer.jsx
Adds onError prop and PropTypes; introduces loadError and retryKey state with handleRetry to remount the viewer; adds PdfLoadError/renderError using Ant Design Result with a Retry action; propagates load errors to parent via onError; clears error on fileUrl change; minor guard refinements for highlight data and empty-file handling.
PDF Viewer Styles
frontend/src/components/custom-tools/pdf-viewer/Highlight.css
Adds .pdf-viewer-error styles (flex centering, full/min height, light background, rounded corners) and nested .ant-result typography/padding rules for centered error UI presentation.

Sequence Diagram

sequenceDiagram
    participant User as User
    participant PdfViewer as PdfViewer
    participant Viewer as Viewer
    participant Parent as Parent

    User->>PdfViewer: Request load/open PDF (fileUrl)
    PdfViewer->>Viewer: Render with current `key`/fileUrl
    Viewer-->>PdfViewer: Emit load error (callback)
    PdfViewer->>PdfViewer: set `loadError`, call `renderError`
    PdfViewer->>Parent: call `onError(loadError)` (if provided)
    PdfViewer->>User: display AntD Result error UI with Retry
    User->>PdfViewer: click Retry
    PdfViewer->>PdfViewer: increment `retryKey`, clear `loadError` (forces remount)
    PdfViewer->>Viewer: re-render with new `key` to retry load
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 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 (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: adding error fallback handling for the PDF viewer component when document loading fails.
Description check ✅ Passed The description is comprehensive and covers all required template sections with detailed explanations of what changed, why it was needed, and how it was implemented.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/pdf-viewer-error-fallback

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 and usage tips.

@sonarqubecloud
Copy link

sonarqubecloud bot commented Feb 6, 2026

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@frontend/src/components/custom-tools/pdf-viewer/PdfViewer.jsx`:
- Around line 34-66: renderError currently calls the onError callback during
render which causes a side effect; instead, have renderError set a local error
state (useState) and remove the direct onError call, then add a useEffect that
watches that error state and invokes onError(error) when the state changes
(include onError in the effect deps and guard for non-null error). Update
references to renderError, onError, handleRetry and the new error state variable
so renderError remains pure and the notification happens in useEffect.
🧹 Nitpick comments (1)
frontend/src/components/custom-tools/pdf-viewer/Highlight.css (1)

11-36: Consider using Ant Design theme tokens instead of hardcoded colors.

The colors (#fafafa, #262626, #8c8c8c, etc.) are hardcoded, which won't adapt if the application ever adopts a dark theme or customizes its Ant Design theme tokens. Additionally, directly overriding .ant-result-title / .ant-result-subtitle class names couples this to antd's internal markup — these can break on major antd upgrades.

Not a blocker given the rest of the file already uses hardcoded values, but worth noting for future maintainability.

Copy link
Contributor

@jaseemjaskp jaseemjaskp left a comment

Choose a reason for hiding this comment

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

LGTM. please review the coderabbit comment and address it if valid. otherwise resolve it

Avoid side effects during render by storing the error in state
and notifying the parent via useEffect instead of calling onError
directly inside renderError.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Resolve import ordering conflict with main branch and fix biome
lint warnings (missing block statements, trailing comma).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
frontend/src/components/custom-tools/pdf-viewer/PdfViewer.jsx (1)

45-52: ⚠️ Potential issue | 🟠 Major

Keep renderError side-effect free.

Line 52 still updates PdfViewer state from inside Viewer's render callback. React can warn on this (Cannot update a component while rendering a different component), and if the PDF library hands back a fresh error object each render you'll re-notify the parent repeatedly. Please move the error capture to a post-render/library event path and let renderError only return UI.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/components/custom-tools/pdf-viewer/PdfViewer.jsx` around lines
45 - 52, renderError currently mutates PdfViewer state by calling setLoadError
inside the Viewer render callback; remove that side-effect so renderError only
returns UI, and instead capture/notify errors in a post-render path (e.g.,
attach the PDF library's onDocumentLoadError/onError callback or use a useEffect
that watches an errorRef/state set from the library event). Concretely: remove
setLoadError from renderError, add a dedicated handler (e.g.,
handleDocumentError) wired to the library's event props or update a
ref/errorState from that handler, then use useEffect inside PdfViewer to call
setLoadError/notify parent when that handler updates the ref/state; keep
references to renderError, setLoadError, and the new
handleDocumentError/useEffect to locate and modify the code.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@frontend/src/components/custom-tools/pdf-viewer/PdfViewer.jsx`:
- Around line 45-52: renderError currently mutates PdfViewer state by calling
setLoadError inside the Viewer render callback; remove that side-effect so
renderError only returns UI, and instead capture/notify errors in a post-render
path (e.g., attach the PDF library's onDocumentLoadError/onError callback or use
a useEffect that watches an errorRef/state set from the library event).
Concretely: remove setLoadError from renderError, add a dedicated handler (e.g.,
handleDocumentError) wired to the library's event props or update a
ref/errorState from that handler, then use useEffect inside PdfViewer to call
setLoadError/notify parent when that handler updates the ref/state; keep
references to renderError, setLoadError, and the new
handleDocumentError/useEffect to locate and modify the code.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 124c7964-8ea5-472e-9daf-dcde9d38c141

📥 Commits

Reviewing files that changed from the base of the PR and between b2c4fb3 and 0661cab.

📒 Files selected for processing (1)
  • frontend/src/components/custom-tools/pdf-viewer/PdfViewer.jsx

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
frontend/src/components/custom-tools/pdf-viewer/PdfViewer.jsx (1)

22-22: Consider wiring onError in parent components for coordinated error handling.

The relevant code snippets show that OutputAnalyzerCard and DocumentManager currently invoke PdfViewer without passing onError. While the internal error UI provides user feedback, parent components could benefit from being notified to update their own state (e.g., resetting isContentAvailable in DocumentViewer). This can be addressed as a follow-up enhancement.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/components/custom-tools/pdf-viewer/PdfViewer.jsx` at line 22,
PdfViewer currently accepts an onError prop but parent components (notably
OutputAnalyzerCard and DocumentManager) are not passing it, preventing parents
from reacting to viewer errors; update the parent components that render
PdfViewer (e.g., where PdfViewer(...) is invoked in OutputAnalyzerCard and
DocumentManager) to accept or create an onError callback and pass it down (for
example a handler that updates parent state such as resetting isContentAvailable
or triggering their own error UI), and ensure PdfViewer calls that onError
whenever it currently triggers its internal error UI so parents are notified.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@frontend/src/components/custom-tools/pdf-viewer/PdfViewer.jsx`:
- Around line 28-42: The component retains a stale loadError when fileUrl
changes, which can cause the existing useEffect (that notifies onError) to send
outdated errors; add a new effect that resets loadError by calling
setLoadError(null) whenever fileUrl changes (so the state and notifications
reflect the current file), or modify the existing effects to include fileUrl in
their dependency and clear loadError before notifying; update references to
retryKey/handleRetry only if they rely on the old loadError semantics.

---

Nitpick comments:
In `@frontend/src/components/custom-tools/pdf-viewer/PdfViewer.jsx`:
- Line 22: PdfViewer currently accepts an onError prop but parent components
(notably OutputAnalyzerCard and DocumentManager) are not passing it, preventing
parents from reacting to viewer errors; update the parent components that render
PdfViewer (e.g., where PdfViewer(...) is invoked in OutputAnalyzerCard and
DocumentManager) to accept or create an onError callback and pass it down (for
example a handler that updates parent state such as resetting isContentAvailable
or triggering their own error UI), and ensure PdfViewer calls that onError
whenever it currently triggers its internal error UI so parents are notified.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 91ef3ba0-a250-4830-bfcc-87e40bc4806b

📥 Commits

Reviewing files that changed from the base of the PR and between 0661cab and ec65b0f.

📒 Files selected for processing (2)
  • frontend/src/components/custom-tools/pdf-viewer/Highlight.css
  • frontend/src/components/custom-tools/pdf-viewer/PdfViewer.jsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • frontend/src/components/custom-tools/pdf-viewer/Highlight.css

…ions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@frontend/src/components/custom-tools/pdf-viewer/PdfViewer.jsx`:
- Around line 42-47: PdfViewer load failures aren't propagated because the
wrapper render paths create PdfViewer without the onError prop and some wrapper
components short-circuit when fileUrl is empty; wire the onError handler through
the wrapper layer where PdfViewer is instantiated (look for the PdfViewer render
sites inside DocumentManager and DocumentViewer wrappers) so the parent receives
loadError notifications, or alternatively move the "No PDF Available"
empty-state rendering into the wrapper that decides whether to render PdfViewer;
update the render branches that short-circuit on empty fileUrl to either pass a
noop/onError callback into PdfViewer or handle the empty-state UI at that
wrapper level (ensure symbols PdfViewer and the wrapper render functions in
DocumentManager/DocumentViewer propagate the onError prop).
- Around line 49-79: renderError currently calls setLoadError inside the render
callback which is a render-phase side effect; remove the setLoadError call from
the useCallback (renderError) so it only returns JSX, and instead add a
useEffect that watches the loadError state (the state paired with setLoadError)
and performs any notification/side-effects to the parent when loadError changes;
keep renderError signature and dependencies (handleRetry) intact and ensure the
new useEffect sets/handles the error outside of render.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 441e3e05-8eef-444c-abc0-978123a65a91

📥 Commits

Reviewing files that changed from the base of the PR and between ec65b0f and d1ac6d6.

📒 Files selected for processing (2)
  • frontend/src/components/custom-tools/pdf-viewer/Highlight.css
  • frontend/src/components/custom-tools/pdf-viewer/PdfViewer.jsx
✅ Files skipped from review due to trivial changes (1)
  • frontend/src/components/custom-tools/pdf-viewer/Highlight.css

Move error UI and reporting into a separate PdfLoadError component
that uses useEffect for setLoadError, keeping renderError pure
(returns JSX only, no state setters during render).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions
Copy link
Contributor

github-actions bot commented Mar 9, 2026

Frontend Lint Report (Biome)

All checks passed! No linting or formatting issues found.

@sonarqubecloud
Copy link

sonarqubecloud bot commented Mar 9, 2026

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
frontend/src/components/custom-tools/pdf-viewer/PdfViewer.jsx (1)

22-45: Add PropTypes for the PdfLoadError component.

SonarCloud flags missing prop validation for error, onRetry, and reportError. While this is an internal component, adding PropTypes maintains consistency with PdfViewer and aids documentation.

💡 Proposed fix to add PropTypes
+PdfLoadError.propTypes = {
+  error: PropTypes.shape({
+    message: PropTypes.string,
+  }),
+  onRetry: PropTypes.func.isRequired,
+  reportError: PropTypes.func.isRequired,
+};
+
 function PdfViewer({ fileUrl, highlightData, currentHighlightIndex, onError }) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/components/custom-tools/pdf-viewer/PdfViewer.jsx` around lines
22 - 45, PdfLoadError is missing PropTypes for its props; import PropTypes at
the top of the file and add a PdfLoadError.propTypes definition that validates
error (object or null), onRetry (function) and reportError (function), marking
onRetry and reportError as required if they must always be provided; keep types
consistent with how PdfViewer uses these props.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@frontend/src/components/custom-tools/pdf-viewer/PdfViewer.jsx`:
- Around line 22-45: PdfLoadError is missing PropTypes for its props; import
PropTypes at the top of the file and add a PdfLoadError.propTypes definition
that validates error (object or null), onRetry (function) and reportError
(function), marking onRetry and reportError as required if they must always be
provided; keep types consistent with how PdfViewer uses these props.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8c64a38a-3497-42ae-a379-fd655f3e7773

📥 Commits

Reviewing files that changed from the base of the PR and between d1ac6d6 and 74afd7c.

📒 Files selected for processing (1)
  • frontend/src/components/custom-tools/pdf-viewer/PdfViewer.jsx

@gaya3-zipstack gaya3-zipstack merged commit c555d46 into main Mar 9, 2026
7 checks passed
@gaya3-zipstack gaya3-zipstack deleted the fix/pdf-viewer-error-fallback branch March 9, 2026 11:23
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.

4 participants