🐛 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 <niwi@niwi.nz>
This commit is contained in:
Andrey Antukh
2026-03-23 20:03:14 +01:00
committed by GitHub
parent 2d616cf9c0
commit b484415a9f
2 changed files with 36 additions and 6 deletions

View File

@@ -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 %))

View File

@@ -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"