Skip to content

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

Open
vishnuszipstack wants to merge 1 commit intomainfrom
fix/pdf-viewer-error-fallback
Open

[FIX] Add error fallback for PDF viewer when document fails to load#1781
vishnuszipstack wants to merge 1 commit 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

Summary by CodeRabbit

Release Notes

  • New Features

    • Added retry functionality for failed PDF loads with an easy-to-use retry button
    • PDF viewer now displays clear messaging when no file is selected
  • Bug Fixes

    • Enhanced error handling and styling in PDF viewer for improved user feedback during load failures
    • Improved visual presentation of error states in the PDF viewer

Walkthrough

The changes add error handling and retry functionality to the PDF viewer component. CSS styling for error states is introduced, and the PdfViewer component is enhanced with retry logic, error display UI using Ant Design components, and a new onError callback prop for parent component error reporting.

Changes

Cohort / File(s) Summary
PDF Viewer Error Handling
frontend/src/components/custom-tools/pdf-viewer/Highlight.css, frontend/src/components/custom-tools/pdf-viewer/PdfViewer.jsx
Added CSS styling for error state rendering with flex layout and typography. Enhanced PdfViewer with retry state/callback, error display UI via Ant Design Result component, empty URL handling, and new onError prop for error callbacks to parent components.

Sequence Diagram

sequenceDiagram
    participant User
    participant PdfViewer
    participant Viewer
    participant Parent
    
    User->>Viewer: Load PDF
    Viewer-->>PdfViewer: Error occurs
    PdfViewer->>PdfViewer: Trigger renderError()
    PdfViewer->>User: Display error UI with retry button
    Parent->>Parent: Receive onError callback
    User->>PdfViewer: Click retry button
    PdfViewer->>PdfViewer: Update retryKey state
    PdfViewer->>Viewer: Re-render with new key
    Viewer->>User: Attempt PDF load again
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 summarizes the main change: adding error fallback handling for PDF viewer load failures, which aligns with the changeset.
Description check ✅ Passed The description is comprehensive and complete, covering all required sections from the template including What, Why, How, feature breakage assessment, testing notes, and dependencies.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 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.

Comment on lines +34 to +66
// Render error fallback for PDF load failures
const renderError = useCallback(
(error) => {
const errorMessage =
error?.message ||
"Failed to load PDF document. The file may be corrupted or inaccessible.";

// Notify parent component of error if callback provided
if (onError) {
onError(error);
}

return (
<div className="pdf-viewer-error">
<Result
icon={<FileExclamationOutlined style={{ color: "#ff4d4f" }} />}
title="Failed to Load PDF"
subTitle={errorMessage}
extra={
<Button
type="primary"
icon={<ReloadOutlined />}
onClick={handleRetry}
>
Retry
</Button>
}
/>
</div>
);
},
[onError, handleRetry]
);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Side effect in render callback: onError is invoked during render.

renderError is a render callback — React can invoke it multiple times (reconciliation, Strict Mode double-render, etc.). Calling onError(error) directly inside it triggers a side effect during render, which can cause duplicate notifications to the parent and violates React's expectation that render functions are pure.

Move the error notification into a useEffect instead, tracking the error in state:

Proposed fix
- const [retryKey, setRetryKey] = useState(0);
+ const [retryKey, setRetryKey] = useState(0);
+ const [loadError, setLoadError] = useState(null);
+
  const handleRetry = useCallback(() => {
    setRetryKey((prev) => prev + 1);
+   setLoadError(null);
  }, []);

+ // Notify parent of load errors
+ useEffect(() => {
+   if (loadError && onError) {
+     onError(loadError);
+   }
+ }, [loadError, onError]);

  const renderError = useCallback(
    (error) => {
      const errorMessage =
        error?.message ||
        "Failed to load PDF document. The file may be corrupted or inaccessible.";

-     if (onError) {
-       onError(error);
-     }
+     // Store error in state so useEffect can safely notify parent
+     setLoadError(error);

      return (
        <div className="pdf-viewer-error">
          <Result
            icon={<FileExclamationOutlined style={{ color: "#ff4d4f" }} />}
            title="Failed to Load PDF"
            subTitle={errorMessage}
            extra={
              <Button
                type="primary"
                icon={<ReloadOutlined />}
                onClick={handleRetry}
              >
                Retry
              </Button>
            }
          />
        </div>
      );
    },
-   [onError, handleRetry]
+   [handleRetry]
  );
🤖 Prompt for AI Agents
In `@frontend/src/components/custom-tools/pdf-viewer/PdfViewer.jsx` around lines
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.

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

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.

3 participants