diff --git a/frontend/src/uxbox/main/ui.cljs b/frontend/src/uxbox/main/ui.cljs index 0cbb1adc2..429c14881 100644 --- a/frontend/src/uxbox/main/ui.cljs +++ b/frontend/src/uxbox/main/ui.cljs @@ -23,12 +23,12 @@ [uxbox.main.ui.profile.register :refer [profile-register-page]] [uxbox.main.ui.profile.recovery-request :refer [profile-recovery-request-page]] [uxbox.main.ui.profile.recovery :refer [profile-recovery-page]] - [uxbox.main.ui.dashboard :as dashboard] [uxbox.main.ui.settings :as settings] [uxbox.main.ui.shapes] [uxbox.main.ui.workspace :as workspace] [uxbox.util.data :refer [parse-int uuid-str?]] + [uxbox.util.components :refer [wrap-catch]] [uxbox.util.dom :as dom] [uxbox.util.html.history :as html-history] [uxbox.util.i18n :refer [tr]] @@ -60,7 +60,15 @@ ["/workspace/:file-id" :workspace]]) +(mf/defc app-error + [{:keys [error] :as props}] + (let [data (ex-data error)] + (case (:type data) + :not-found [:span "404"] + [:span "Internal application errror"]))) + (mf/defc app + {:wrap [#(wrap-catch % app-error)]} [props] (let [route (mf/deref route-iref)] (case (get-in route [:data :name]) diff --git a/frontend/src/uxbox/util/components.cljs b/frontend/src/uxbox/util/components.cljs index f4bf8aa1a..9a7cb52c1 100644 --- a/frontend/src/uxbox/util/components.cljs +++ b/frontend/src/uxbox/util/components.cljs @@ -49,3 +49,28 @@ #(rx/cancel! sub))) #js [ob]) state)) + +(defn wrap-catch + ([component error-component] (wrap-catch component error-component (constantly nil))) + ([component error-component on-error] + (let [ctor (fn [props] + (this-as this + (unchecked-set this "state" #js {}) + (.call js/React.Component this props))) + _ (goog/inherits ctor js/React.Component) + prot (unchecked-get ctor "prototype")] + (unchecked-set ctor "displayName" (str "Catch(" (unchecked-get component "displayName") ")")) + (unchecked-set ctor "getDerivedStateFromError" (fn [error] #js {:error error})) + (unchecked-set prot "componentDidCatch" (fn [e i] (on-error e i))) + (unchecked-set prot "render" + (fn [] + (this-as this + (let [state (unchecked-get this "state") + error (unchecked-get state "error")] + (if error + (mf/element error-component #js {:error error}) + (mf/element component #js {})))))) + + ctor))) + +