From 0418147e74ccc9391a2d768af871d84098d49541 Mon Sep 17 00:00:00 2001 From: Globalstar117 Date: Sat, 17 Jan 2026 02:08:39 +1100 Subject: [PATCH 1/3] :bug: Add error handler to token form validation to prevent crash When creating a token with a name that conflicts with existing hierarchical token names (e.g., 'accent-color' when 'accent-color.blue.dark' exists), the validation throws an error via rx/throw. However, the rx/subs! subscriber in generic_form.cljs had no error handler, causing an unhandled exception that resulted in an 'Internal Error' crash. This fix adds an error handler that: 1. Catches validation errors from the reactive stream 2. Uses humanize-errors to convert them to user-friendly messages 3. Displays the error in the form's extra-errors field Before: Crash with 'Internal Error' dialog After: Form shows validation error message Fixes #8110 --- This is a Gittensor contribution. gittensor:user:GlobalStar117 --- .../workspace/tokens/management/forms/generic_form.cljs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/frontend/src/app/main/ui/workspace/tokens/management/forms/generic_form.cljs b/frontend/src/app/main/ui/workspace/tokens/management/forms/generic_form.cljs index c5ab6a428a..5348ee2d8a 100644 --- a/frontend/src/app/main/ui/workspace/tokens/management/forms/generic_form.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/management/forms/generic_form.cljs @@ -18,6 +18,7 @@ [app.main.data.workspace.tokens.application :as dwta] [app.main.data.workspace.tokens.library-edit :as dwtl] [app.main.data.workspace.tokens.propagation :as dwtp] + [app.main.data.workspace.tokens.errors :as wte] [app.main.data.workspace.tokens.remapping :as remap] [app.main.refs :as refs] [app.main.store :as st] @@ -224,7 +225,12 @@ :description description})) (dwtl/toggle-token-path path) (dwtp/propagate-workspace-tokens) - (modal/hide!))))))))))] + (modal/hide!))))) + ;; Error handler: display validation errors in the form instead of crashing + (fn [{:keys [errors]}] + (let [error-messages (wte/humanize-errors errors) + error-message (first error-messages)] + (swap! form assoc-in [:extra-errors :value] {:message error-message}))))))))] [:> fc/form* {:class (stl/css :form-wrapper) :form form From 1c2c0987f5fd051438590c9c4201573648482cd0 Mon Sep 17 00:00:00 2001 From: Eva Marco Date: Mon, 19 Jan 2026 14:01:37 +0100 Subject: [PATCH 2/3] :bug: Fix schema validation for references from other sets --- frontend/src/app/main/refs.cljs | 3 +++ .../management/forms/controls/color_input.cljs | 10 +++++++++- .../tokens/management/forms/form_container.cljs | 14 ++++++-------- .../tokens/management/forms/generic_form.cljs | 14 ++++++++------ frontend/translations/es.po | 2 +- 5 files changed, 27 insertions(+), 16 deletions(-) diff --git a/frontend/src/app/main/refs.cljs b/frontend/src/app/main/refs.cljs index 3577842a07..b443af8b2e 100644 --- a/frontend/src/app/main/refs.cljs +++ b/frontend/src/app/main/refs.cljs @@ -483,6 +483,9 @@ (def workspace-active-theme-paths (l/derived (d/nilf ctob/get-active-theme-paths) tokens-lib)) +(def workspace-all-tokens-map + (l/derived (d/nilf ctob/get-all-tokens-map) tokens-lib)) + (defn token-sets-at-path-all-active [group-path] (l/derived diff --git a/frontend/src/app/main/ui/workspace/tokens/management/forms/controls/color_input.cljs b/frontend/src/app/main/ui/workspace/tokens/management/forms/controls/color_input.cljs index ce18196c22..a4bfbf1b0c 100644 --- a/frontend/src/app/main/ui/workspace/tokens/management/forms/controls/color_input.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/management/forms/controls/color_input.cljs @@ -140,6 +140,9 @@ error (get-in @form [:errors input-name]) + extra-error + (get-in @form [:extra-errors input-name]) + value (get-in @form [:data input-name] "") @@ -247,9 +250,14 @@ :hint-type (:type hint)}) props - (if (and error touched?) + (cond + (and error touched?) (mf/spread-props props {:hint-type "error" :hint-message (:message error)}) + (and extra-error touched?) + (mf/spread-props props {:hint-type "error" + :hint-message (:message extra-error)}) + :else props)] (mf/with-effect [resolve-stream tokens token input-name] diff --git a/frontend/src/app/main/ui/workspace/tokens/management/forms/form_container.cljs b/frontend/src/app/main/ui/workspace/tokens/management/forms/form_container.cljs index 0d968beab0..af394eadee 100644 --- a/frontend/src/app/main/ui/workspace/tokens/management/forms/form_container.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/management/forms/form_container.cljs @@ -23,21 +23,19 @@ (let [token-type (or (:type token) token-type) - tokens-in-selected-set - (mf/deref refs/workspace-all-tokens-in-selected-set) - token-path (mf/with-memo [token] (cft/token-name->path (:name token))) - tokens-tree-in-selected-set - (mf/with-memo [token-path tokens-in-selected-set] - (-> (ctob/tokens-tree tokens-in-selected-set) + all-tokens (mf/deref refs/workspace-all-tokens-map) + + all-tokens + (mf/with-memo [token-path all-tokens] + (-> (ctob/tokens-tree all-tokens) (d/dissoc-in token-path))) props (mf/spread-props props {:token-type token-type - :tokens-tree-in-selected-set tokens-tree-in-selected-set - :tokens-in-selected-set tokens-in-selected-set + :all-token-tree all-tokens :token token}) text-case-props (mf/spread-props props {:input-value-placeholder (tr "workspace.tokens.text-case-value-enter")}) text-decoration-props (mf/spread-props props {:input-value-placeholder (tr "workspace.tokens.text-decoration-value-enter")}) diff --git a/frontend/src/app/main/ui/workspace/tokens/management/forms/generic_form.cljs b/frontend/src/app/main/ui/workspace/tokens/management/forms/generic_form.cljs index 5348ee2d8a..69ade9d635 100644 --- a/frontend/src/app/main/ui/workspace/tokens/management/forms/generic_form.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/management/forms/generic_form.cljs @@ -16,9 +16,9 @@ [app.main.data.helpers :as dh] [app.main.data.modal :as modal] [app.main.data.workspace.tokens.application :as dwta] + [app.main.data.workspace.tokens.errors :as wte] [app.main.data.workspace.tokens.library-edit :as dwtl] [app.main.data.workspace.tokens.propagation :as dwtp] - [app.main.data.workspace.tokens.errors :as wte] [app.main.data.workspace.tokens.remapping :as remap] [app.main.refs :as refs] [app.main.store :as st] @@ -89,14 +89,13 @@ action is-create selected-token-set-id - tokens-tree-in-selected-set + all-token-tree token-type make-schema input-component initial type value-subfield - tokens-in-selected-set input-value-placeholder] :as props}] (let [make-schema (or make-schema default-make-schema) @@ -125,6 +124,9 @@ tokens (mf/deref refs/workspace-active-theme-sets-tokens) + tokens-in-selected-set + (mf/deref refs/workspace-all-tokens-in-selected-set) + tokens (mf/with-memo [tokens tokens-in-selected-set token] ;; Ensure that the resolved value uses the currently editing token @@ -135,8 +137,8 @@ (assoc (:name token) token))) schema - (mf/with-memo [tokens-tree-in-selected-set active-tab] - (make-schema tokens-tree-in-selected-set active-tab)) + (mf/with-memo [all-token-tree active-tab] + (make-schema all-token-tree active-tab)) initial (mf/with-memo [token] @@ -226,7 +228,7 @@ (dwtl/toggle-token-path path) (dwtp/propagate-workspace-tokens) (modal/hide!))))) - ;; Error handler: display validation errors in the form instead of crashing + ;; WORKAROUND: display validation errors in the form instead of crashing (fn [{:keys [errors]}] (let [error-messages (wte/humanize-errors errors) error-message (first error-messages)] diff --git a/frontend/translations/es.po b/frontend/translations/es.po index f707ca20ee..10552a09eb 100644 --- a/frontend/translations/es.po +++ b/frontend/translations/es.po @@ -7965,7 +7965,7 @@ msgstr "Line height (multiplicador, px o %) o {alias}" #: src/app/main/data/workspace/tokens/errors.cljs:57 msgid "workspace.tokens.missing-references" -msgstr "Referéncias de tokens no encontradas:" +msgstr "Referencias de tokens no encontradas: " #: src/app/main/ui/workspace/tokens/management/token_pill.cljs:123 msgid "workspace.tokens.more-options" From cecd3d4a901af610ebe3684363a8177a1a1bde87 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 20 Jan 2026 16:00:57 +0100 Subject: [PATCH 3/3] :paperclip: Update changelog --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 2f032008fb..379c6fe641 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -24,6 +24,7 @@ - Fix wrong register image [Taiga #12955](https://tree.taiga.io/project/penpot/task/12955) - Fix error message on components doesn't close automatically [Taiga #12012](https://tree.taiga.io/project/penpot/issue/12012) - Fix incorrect default option on tokens import dialog [Github #8051](https://github.com/penpot/penpot/pull/8051) +- Fix unhandled exception tokens creation dialog [Github #8110](https://github.com/penpot/penpot/issues/8110) ## 2.13.0 (Unreleased)