From b484415a9ff1b107151cdb81246da14f9598609e Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Mon, 23 Mar 2026 20:03:14 +0100 Subject: [PATCH] :bug: Fix generic error shown on clipboard permission denial (#8666) When the browser denies clipboard read permission (NotAllowedError), the unhandled exception handler was showing a generic 'Something wrong has happened' toast. This change adds proper error handling for clipboard permission errors in paste operations and shows a user-friendly warning message instead. Changes: - Add error handling in paste-from-clipboard for NotAllowedError - Improve error handling in paste-selected-props to detect permission errors - Mark clipboard NotAllowedError as ignorable in the uncaught error handler to prevent duplicate generic error toasts - Add translation key for clipboard permission denied message Signed-off-by: Andrey Antukh --- .../app/main/data/workspace/clipboard.cljs | 38 ++++++++++++++++--- frontend/translations/en.po | 4 ++ 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/frontend/src/app/main/data/workspace/clipboard.cljs b/frontend/src/app/main/data/workspace/clipboard.cljs index 4bd8190895..e32de485e5 100644 --- a/frontend/src/app/main/data/workspace/clipboard.cljs +++ b/frontend/src/app/main/data/workspace/clipboard.cljs @@ -294,6 +294,22 @@ (def default-paste-from-blob (create-paste-from-blob false)) +(defn- clipboard-permission-error? + "Check if the given error is a clipboard permission error + (NotAllowedError DOMException)." + [cause] + (and (instance? js/DOMException cause) + (= (.-name cause) "NotAllowedError"))) + +(defn- on-clipboard-permission-error + [cause] + (if (clipboard-permission-error? cause) + (rx/of (ntf/show {:content (tr "errors.clipboard-permission-denied") + :type :toast + :level :warning + :timeout 5000})) + (rx/throw cause))) + (defn paste-from-clipboard "Perform a `paste` operation using the Clipboard API." [] @@ -302,7 +318,8 @@ (watch [_ _ _] (->> (clipboard/from-navigator default-options) (rx/mapcat default-paste-from-blob) - (rx/take 1))))) + (rx/take 1) + (rx/catch on-clipboard-permission-error))))) (defn paste-from-event "Perform a `paste` operation from user emmited event." @@ -482,11 +499,20 @@ (-> entry t/decode-str paste-transit-props)) (on-error [cause] - (let [data (ex-data cause)] - (if (:not-implemented data) - (rx/of (ntf/warn (tr "errors.clipboard-not-implemented"))) - (js/console.error "Clipboard error:" cause)) - (rx/empty)))] + (cond + (clipboard-permission-error? cause) + (rx/of (ntf/show {:content (tr "errors.clipboard-permission-denied") + :type :toast + :level :warning + :timeout 5000})) + + (:not-implemented (ex-data cause)) + (rx/of (ntf/warn (tr "errors.clipboard-not-implemented"))) + + :else + (do + (js/console.error "Clipboard error:" cause) + (rx/empty))))] (->> (clipboard/from-navigator default-options) (rx/mapcat #(.text %)) diff --git a/frontend/translations/en.po b/frontend/translations/en.po index 495fd1b9c2..a39cfaf85c 100644 --- a/frontend/translations/en.po +++ b/frontend/translations/en.po @@ -1375,6 +1375,10 @@ msgstr "Character limit exceeded" msgid "errors.clipboard-not-implemented" msgstr "Your browser cannot do this operation" +#: src/app/main/data/workspace/clipboard.cljs +msgid "errors.clipboard-permission-denied" +msgstr "Clipboard access denied. Please allow clipboard permissions in your browser to paste content" + #: src/app/main/errors.cljs:235 msgid "errors.comment-error" msgstr "There was an error with the comment"