Skip to content

Fix BL-16459 Copying Text Failed#7992

Open
andrew-polk wants to merge 1 commit into
masterfrom
BL-16459-clipboard-copy-error
Open

Fix BL-16459 Copying Text Failed#7992
andrew-polk wants to merge 1 commit into
masterfrom
BL-16459-clipboard-copy-error

Conversation

@andrew-polk

@andrew-polk andrew-polk commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

https://issues.bloomlibrary.org/youtrack/issue/BL-16459

The common/clipboardText endpoint copies/pastes text via the Windows
clipboard. When another program is momentarily holding the clipboard,
Windows throws System.Runtime.InteropServices.ExternalException
("Requested Clipboard operation did not succeed"). This is transient and
external to Bloom (the underlying Clipboard.SetText overload already
retries), but the handler reported it with ModalIf.All, popping a scary
"report this problem" dialog the user can do nothing about but retry.

Now both the copy (SetText) and paste (GetText) paths catch
ExternalException separately and downgrade to a gentle, non-modal toast
(ModalIf.None/PassiveIf.All, showSendReport: false) via a new
ReportClipboardBusy helper. It still logs and reports to Sentry so we can
track frequency. Any other unexpected exception keeps the existing modal
report. The toast reuses the existing localized EditTab.Image.CopyImageFailed
string already used by EditingView.CopyImageToClipboard's ExternalException
handler (though that handler uses a modal MessageBox and does not report to
Sentry).

Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

Devin review


This change is Reviewable

https://issues.bloomlibrary.org/youtrack/issue/BL-16459

The common/clipboardText endpoint copies/pastes text via the Windows
clipboard. When another program is momentarily holding the clipboard,
Windows throws System.Runtime.InteropServices.ExternalException
("Requested Clipboard operation did not succeed"). This is transient and
external to Bloom (the underlying Clipboard.SetText overload already
retries), but the handler reported it with ModalIf.All, popping a scary
"report this problem" dialog the user can do nothing about but retry.

Now both the copy (SetText) and paste (GetText) paths catch
ExternalException separately and downgrade to a gentle, non-modal toast
(ModalIf.None/PassiveIf.All, showSendReport: false) via a new
ReportClipboardBusy helper. It still logs and reports to Sentry so we can
track frequency. Any other unexpected exception keeps the existing modal
report. The toast reuses the existing localized EditTab.Image.CopyImageFailed
string already used by EditingView.CopyImageToClipboard's ExternalException
handler (though that handler uses a modal MessageBox and does not report to
Sentry).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@greptile-apps

greptile-apps Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR narrows clipboard error handling in the common/clipboardText API endpoint to distinguish transient OS-level clipboard contention (ExternalException) from genuine unexpected errors. Previously any exception triggered a modal problem-report dialog; now ExternalException surfaces as a quiet toast while all other exceptions continue to use the existing modal path.

  • Adds a catch (ExternalException) block before the existing catch (Exception) in both the GET (paste) and POST (copy) paths, so Windows clipboard-busy errors are caught specifically.
  • Introduces ReportClipboardBusy, which calls NonFatalProblem.Report with ModalIf.None / PassiveIf.All / showSendReport: false, showing a toast and sending to Sentry without prompting the user to file a report.
  • Reuses the existing localized string EditTab.Image.CopyImageFailed for the toast message, keeping the user-visible text consistent with the image-copy path.

Important Files Changed

Filename Overview
src/BloomExe/web/controllers/CommonApi.cs Adds a specific ExternalException catch before the general Exception catch in both the GET (paste) and POST (copy) clipboard paths, downgrading the error UI from a modal problem-report dialog to a non-modal toast via a new ReportClipboardBusy helper. Sentry and local logging are preserved.

Reviews (1): Last reviewed commit: "Fix BL-16459 Copying Text Failed" | Re-trigger Greptile

@hatton hatton left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@hatton made 2 comments.
Reviewable status: 0 of 1 files reviewed, 2 unresolved discussions (waiting on andrew-polk).


src/BloomExe/web/controllers/CommonApi.cs line 122 at r1 (raw file):

                                    result = PortableClipboard.GetText();
                                }
                                catch (ExternalException e)

If I'm reading this right, we are assuming that the problem was that the clipboard is busy. Surely there are other problems possible?


src/BloomExe/web/controllers/CommonApi.cs line 293 at r1 (raw file):

        /// dialog we just show a gentle toast (and still log/send to Sentry so we can track it).
        /// </summary>
        private static void ReportClipboardBusy(ExternalException e)

This should just be a toast. And if you click on it then I think you can get an error report and then they could send the error report.

"Bloom was not able to copy that" / "Bloom was not able to paste".

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.

2 participants