Skip to content

Add workflow settings to skip OCR error notifications for unprocessable PDFs - #337

Merged
R0Wi merged 3 commits into
masterfrom
copilot/add-option-to-skip-ocr-errors
Dec 4, 2025
Merged

R0Wi merged 3 commits into
masterfrom
copilot/add-option-to-skip-ocr-errors

Conversation

Copilot AI commented Nov 24, 2025 •

Copy link
Copy Markdown
Contributor

This PR adds two new per-workflow settings that allow users to suppress error notifications for PDFs that cannot be processed, addressing issue #325 where users were flooded with OcrNotPossibleException errors when uploading folders with many PDFs.

New Workflow Settings

  • skipNotificationsOnInvalidPdf: Suppresses error notifications for PDFs that return OCRmyPDF exit code 2 (digitally signed PDFs, tagged PDFs, or other conditions preventing OCR)
  • skipNotificationsOnEncryptedPdf: Suppresses error notifications for encrypted PDFs that return OCRmyPDF exit code 8

When these settings are enabled, the app logs a debug message and silently skips the file instead of throwing OcrNotPossibleException and creating user notifications.

Architecture Refactoring

The PR includes a significant refactoring from exception-based to result-based error handling:

  • Removed: OcrAlreadyDoneException and OcrResultEmptyException classes
  • Enhanced: OcrProcessorResult now includes exitCode, errorMessage, and success properties
  • Updated: OcrProcessorBase returns structured results instead of throwing exceptions based on exit codes
  • Modified: OcrService interprets exit codes from results and makes decisions about error handling
  • Fixed: Null coalescing for exit codes in OcrMyPdfBasedProcessor and WorkflowOcrRemoteProcessor

UI Improvements

  • Added two toggle switches in the workflow settings UI for the new skip options
  • Created reusable HelpIcon and HelpTextWrapper components for improved user experience
  • Added German translations for new settings

Testing

  • ✅ PHP syntax validation passes
  • ✅ PSALM static analysis passes
  • ✅ JavaScript tests pass (40 tests)
  • ✅ Frontend build succeeds
  • ✅ Added integration tests: testWorkflowOcrSkipsNotificationOnInvalidPdf and testWorkflowOcrSkipsNotificationOnEncryptedPdf
  • ✅ Created test PDFs: document-signed.pdf and document-encrypted.pdf
  • ✅ Updated 37 files with comprehensive unit and integration test coverage

How It Works

  1. OCR processor returns result with exit code (2 for invalid PDFs, 8 for encrypted PDFs)
  2. OcrService checks the exit code and workflow settings
  3. If skip setting is enabled for that exit code, it logs a debug message and returns silently
  4. If skip setting is disabled, it throws OcrNotPossibleException as before, generating a user notification

The error handling logic remains the same, just implemented differently - now based on examining results rather than catching exceptions. This provides better separation of concerns and makes the code more maintainable.

Fixes #325

Original prompt

This section details on the original issue you should resolve

<issue_title>Too many 'OcrNotPossibleException' errors</issue_title>
<issue_description>I keep getting too many errors of type ''OcrNotPossibleException', with the message 'OCRmyPDF exited abnormally with exit-code 2 for file...', especially when uploading a folder that has a lot of PDFs.
The logs show that these errors belong to one of the three categories: TaggedPDFError, DigitalSignatureError & EncryptedPdfError. It would be nice to have an option to turn off ocr attempt for such PDFs, so that the Nextcloud notifications don't get loaded with OCR errors.</issue_description>

<agent_instructions>Check the ocrmypdf return codes at https://ocrmypdf.readthedocs.io/en/latest/advanced.html#return-code-policy. Add a per workflow setting which allows for skipping the mentioned errors</agent_instructions>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI changed the title [WIP] Add option to skip OcrNotPossibleException errors Add workflow setting to skip OCR errors for unprocessable PDFs Nov 24, 2025
Copilot AI requested a review from R0Wi November 24, 2025 21:54
Comment thread lib/OcrProcessors/OcrProcessorBase.php Resolved

Copilot AI commented Nov 25, 2025

Copy link
Copy Markdown
Contributor Author

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • index.php
    • Triggering command: /usr/local/bin/node /usr/local/bin/node /home/REDACTED/work/workflow_ocr/workflow_ocr/node_modules/jest-worker/build/workers/processChild.js (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI requested a review from R0Wi November 25, 2025 21:08
@R0Wi
R0Wi force-pushed the copilot/add-option-to-skip-ocr-errors branch from 9817990 to c4b358f Compare November 27, 2025 05:23
@R0Wi

R0Wi commented Nov 27, 2025

Copy link
Copy Markdown
Contributor

@copilot Tests and PSALM actions are failing. Please check and fix

Copilot AI commented Nov 27, 2025 •

Copy link
Copy Markdown
Contributor Author

@copilot Tests and PSALM actions are failing. Please check and fix

Fixed in commit ca05fbb. Issues resolved:

PSALM:

  • Removed unused $success variable from OcrProcessorBase.php
  • Removed unused isSuccess() method from OcrProcessorResult.php
  • Deleted unused OcrAlreadyDoneException and OcrResultEmptyException classes

PHPUnit:

  • Fixed OcrProcessorResult constructor calls at lines 746 and 816 (was passing string as 3rd argument which should be int exitCode)
  • Updated processor tests to check result properties instead of expecting exceptions

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • index.php
    • Triggering command: /usr/local/bin/node /usr/local/bin/node /home/REDACTED/work/workflow_ocr/workflow_ocr/node_modules/jest-worker/build/workers/processChild.js (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@R0Wi

R0Wi commented Nov 27, 2025

Copy link
Copy Markdown
Contributor

@copilot unittests are failing, please fix. Also, provide a new Integration Testcase (remote test) which uses a signed PDF (to be created first) and processes this one via OCR, while the new "skip" flag is enabled. Check that the expected error message is returned but that no error is logged. Use existing Integration tests against workflow_ocr_backend to get an idea

Copilot AI commented Nov 27, 2025 •

Copy link
Copy Markdown
Contributor Author

@copilot unittests are failing, please fix. Also, provide a new Integration Testcase (remote test) which uses a signed PDF (to be created first) and processes this one via OCR, while the new "skip" fl...

Fixed in commit 2755456.

Unit test fixes:

  • Added null coalescing (?? 0 / ?? 1) for exitCode in OcrMyPdfBasedProcessor.php and WorkflowOcrRemoteProcessor.php to handle cases where getExitCode() returns null

New integration test:

  • Added testWorkflowOcrSkipsSignedPdfWithSkipOcrErrors in OcrBackendServiceTest.php
  • Created document-signed.pdf test file (digitally signed PDF that triggers exit code 2)
  • Test verifies that signed PDFs return exit code 2 (DigitalSignatureError) when processed with skipOcrErrors=true

Regarding rebase: I cannot perform git rebase as it requires force push which I don't have access to. Please rebase the branch on master if needed.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • esm.ubuntu.com
    • Triggering command: /usr/lib/apt/methods/https /usr/lib/apt/methods/https (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@R0Wi
R0Wi force-pushed the copilot/add-option-to-skip-ocr-errors branch from a324830 to b416efd Compare November 30, 2025 18:35
@R0Wi
R0Wi marked this pull request as ready for review November 30, 2025 19:35
@R0Wi
R0Wi requested a review from Copilot November 30, 2025 19:36

Copilot AI 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.

Pull request overview

This PR successfully refactors the OCR error handling from an exception-based approach to a result-based approach, while simultaneously adding a new skipOcrErrors workflow setting. The refactoring improves separation of concerns by having OCR processors return structured results (with exit codes and error messages) rather than throwing exceptions, allowing the service layer to interpret these results and make decisions about error handling.

Key Changes

  • Refactored OcrProcessorResult to include success, exitCode, and errorMessage fields, enabling processors to return detailed status information instead of throwing exceptions
  • Added skipOcrErrors boolean setting to WorkflowSettings that allows users to skip PDFs that return OCRmyPDF exit code 2 (encrypted, digitally signed, or tagged PDFs) instead of failing with errors
  • Updated all OCR processors and tests to use the new result-based approach, eliminating OcrAlreadyDoneException and OcrResultEmptyException classes

Reviewed changes

Copilot reviewed 21 out of 21 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
lib/OcrProcessors/OcrProcessorResult.php Expanded to include success flag, exit code, and error message fields for structured result handling
lib/OcrProcessors/OcrProcessorBase.php Simplified to return OcrProcessorResult directly without throwing exceptions based on exit codes
lib/OcrProcessors/Local/OcrMyPdfBasedProcessor.php Updated to return OcrProcessorResult objects instead of arrays
lib/OcrProcessors/Remote/WorkflowOcrRemoteProcessor.php Updated to return OcrProcessorResult objects for remote processing
lib/OcrProcessors/IOcrProcessor.php Removed exception declarations from interface documentation
lib/Service/OcrService.php Centralized exit code interpretation logic: handles exit code 6 (file has text), exit code 2 (unprocessable PDF), and other error codes
lib/Service/IOcrService.php Removed OcrResultEmptyException from throws documentation
lib/Model/WorkflowSettings.php Added skipOcrErrors property with getter and JSON parsing support
lib/Exception/OcrNotPossibleException.php Modified to accept nullable string and prepend "OCR not possible: " prefix
lib/Exception/OcrResultEmptyException.php Deleted as part of refactoring
lib/Exception/OcrAlreadyDoneException.php Deleted as part of refactoring
src/components/WorkflowOcr.vue Added UI switch for skipOcrErrors setting with label "Skip PDFs that cannot be processed"
tests/Unit/Service/OcrServiceTest.php Extensively updated to test result-based behavior instead of exception-based behavior, including new tests for exit code 2 handling
tests/Unit/Service/EventServiceTest.php Updated OcrProcessorResult constructor calls to match new signature
tests/Unit/OcrProcessors/Remote/WorkflowOcrRemoteProcessorTest.php Updated to assert on result properties instead of expecting exceptions
tests/Unit/OcrProcessors/OcrProcessorBaseTest.php Updated to work with OcrProcessorResult objects
tests/Unit/OcrProcessors/Local/PdfOcrProcessorTest.php Updated to verify results instead of catching exceptions
tests/Unit/OcrProcessors/Local/ImageOcrProcessorTest.php Added missing exit code mock return value
tests/Unit/Model/WorkflowSettingsTest.php Added tests for skipOcrErrors property getter
tests/Integration/Notification/NotificationTest.php Updated expected exception message to include "OCR not possible: " prefix
src/test/components/WorkflowOcr.spec.js Updated all test expectations to include skipOcrErrors: false in JSON output, added new tests for the skipOcrErrors switch

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

You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.

Comment thread tests/Unit/Service/OcrServiceTest.php Resolved
Comment thread src/components/WorkflowOcr.vue Resolved
Comment thread lib/Service/OcrService.php Resolved
@R0Wi
R0Wi force-pushed the copilot/add-option-to-skip-ocr-errors branch from b416efd to 5ec865f Compare December 3, 2025 21:34
@R0Wi
R0Wi requested a review from Copilot December 3, 2025 21:34
@R0Wi

R0Wi commented Dec 3, 2025

Copy link
Copy Markdown
Contributor

@copilot update the PR description and summarize the final changes

Add various options to skip notifications to workflow setting to skip OCR errors for PDFs that cannot be processed

- Remove exception throwing logic from OcrProcessorBase based on exit codes
- Add exitCode and errorMessage properties to OcrProcessorResult
- Move exit code handling logic to OcrService instead of catching exceptions
- Delete OcrSkippedException as it's no longer needed
- Update IOcrProcessor interface to remove exception declarations
- Update all tests to work with new result-based approach instead of exceptions

Signed-off-by: Robin Windey <ro.windey@gmail.com>
@R0Wi
R0Wi force-pushed the copilot/add-option-to-skip-ocr-errors branch from 4311831 to 40f8397 Compare December 3, 2025 21:35

Copilot AI 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.

Pull request overview

Copilot reviewed 30 out of 33 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 thread src/components/WorkflowOcr.vue Resolved
Comment thread src/components/GlobalSettings.vue Resolved

Copilot AI commented Dec 3, 2025

Copy link
Copy Markdown
Contributor Author

@copilot update the PR description and summarize the final changes

Summary

This PR adds two new per-workflow settings (skipNotificationsOnInvalidPdf and skipNotificationsOnEncryptedPdf) that allow users to suppress error notifications for PDFs that cannot be processed, addressing issue #325 where users were flooded with OcrNotPossibleException errors.

Key Changes

1. New Workflow Settings

  • skipNotificationsOnInvalidPdf: Skips notifications for PDFs with exit code 2 (digitally signed, tagged, or other conditions preventing OCR)
  • skipNotificationsOnEncryptedPdf: Skips notifications for encrypted PDFs with exit code 8

2. Architecture Refactoring

Refactored from exception-based to result-based error handling:

  • Deleted: OcrAlreadyDoneException, OcrResultEmptyException
  • Enhanced: OcrProcessorResult now includes exitCode and errorMessage properties
  • Updated: OcrProcessorBase returns structured results instead of throwing exceptions
  • Modified: OcrService interprets exit codes and makes decisions about error handling

3. UI Improvements

  • Added two toggle switches in the workflow settings for skip options
  • Created reusable HelpIcon and HelpTextWrapper components for improved UX
  • Added German translations for new settings

4. Testing

  • Added integration tests for both skip scenarios (testWorkflowOcrSkipsNotificationOnInvalidPdf, testWorkflowOcrSkipsNotificationOnEncryptedPdf)
  • Created test PDFs: document-signed.pdf and document-encrypted.pdf
  • Updated 37 files with comprehensive unit and integration test coverage

How It Works

When a workflow has skip settings enabled:

  1. OCR processor returns result with exit code (2 for invalid PDFs, 8 for encrypted)
  2. OcrService checks the exit code and settings
  3. If skip is enabled, it logs a debug message and returns silently
  4. If skip is disabled, it throws OcrNotPossibleException as before

Files Changed

  • 37 files modified (864 additions, 347 deletions)
  • 2 exception classes removed
  • 3 new components added
  • 2 test PDFs created

Fixes #325

Copilot AI changed the title Add workflow setting to skip OCR errors for unprocessable PDFs Add workflow settings to skip OCR error notifications for unprocessable PDFs Dec 3, 2025
@sonarqubecloud

sonarqubecloud Bot commented Dec 4, 2025

Copy link
Copy Markdown

@R0Wi
R0Wi merged commit e27eaa2 into master Dec 4, 2025
17 checks passed
@R0Wi
R0Wi deleted the copilot/add-option-to-skip-ocr-errors branch December 4, 2025 21:37
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.

Too many 'OcrNotPossibleException' errors

3 participants