Skip to content

Instantly share code, notes, and snippets.

@pesterhazy
Last active May 13, 2017 11:48
Show Gist options
  • Save pesterhazy/60ec2b43709bbc8d8a7c324077466df1 to your computer and use it in GitHub Desktop.
Save pesterhazy/60ec2b43709bbc8d8a7c324077466df1 to your computer and use it in GitHub Desktop.
Testing pesterhazy/recalcitrant error-boundary for reagent
;loaded from gist: https://gist.github.com/pesterhazy/60ec2b43709bbc8d8a7c324077466df1
(ns my.test
(:require [reagent.core :as r]
[reagent.impl.component :as comp]
[reagent.impl.util :as util]
[reagent.debug :refer-macros [dev?]]
[goog.object :as gobj]))
(enable-console-print!)
(def error-boundary
"Wrapper component for recovering from exceptions in downstream
render fns. Creates an error boundary that prevents exceptions from corrupting
the React component hierarchy.
Use this component to wrap a single reagent (root) component. Any exception
thrown in downstream render fns will be caught and logged. The component's
child and its children will not be rendered.
This is useful in a reloading-based development workflow.
Example usage:
(ns my-ns
(:require [error-boundary.error-boundary :refer [error-boundary]]))
(r/render-component (fn [] [error-boundary [root]])
(.. js/document (querySelector \"#container\")))
Note that this relies on the undocumented unstable_handleError API introduced
in React 15.
This componenet may have performance implications, so it is recommended to
enable it only during development."
(if (dev?)
(r/adapt-react-class (comp/create-class
{:getInitialState
(fn []
#js {:error false})
:unstable_handleError
(fn [e]
(this-as this
(if (ex-data e)
(js/console.error (pr-str e))
(js/console.error e))
(.setState this #js {:error true})))
:render
(fn []
(this-as this
(let [children ((-> util/react
(gobj/get "Children")
(gobj/get "toArray"))
(-> this
(gobj/get "props")
(gobj/get "children")))]
(when (not= 1 (count children))
(js/console.warn "Component error-boundary requires a single child component. Additional children are ignored."))
(if (-> this
(gobj/get "state")
(gobj/get "error"))
(do
(js/console.warn "An error occurred downstream (see errors above). The element subtree will not be rendered.")
nil)
(first children)))))}))
(r/adapt-react-class (comp/create-class
{:render
(fn []
(this-as this
(let [children ((-> util/react
(gobj/get "Children")
(gobj/get "toArray"))
(-> this
(gobj/get "props")
(gobj/get "children")))]
(first children))))}))))
(defn explode []
;; remove comment to cause an exception.
;; add comment back in to see component recover
#_(throw "kaboom")
[:div "All good"])
(defn root []
[:div
[:h1 "Error boundary test"]
[explode]])
(r/render (fn [] [error-boundary [root]]) js/klipse-container)
@pesterhazy
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment