Instantly share code, notes, and snippets.

What would you like to do?
Reagent error boundary for recovering from exceptions
(ns error-boundary.error-boundary
(:require [reagent.core :as r]
[reagent.impl.component :as comp]
[reagent.impl.util :as util]
[goog.object :as gobj]))
;; (c) 2016 Paulus Esterhazy
;; License: MIT
;; Store in a file called error_boundary/error_boundary.cljs in your classpath.
;; Tested with reagent 0.6.0
;; See
(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."
(r/adapt-react-class (comp/create-class
(fn []
#js {:error false})
(fn [e]
(this-as this
(if (ex-data e)
(js/console.error (pr-str e))
(js/console.error e))
(.setState this #js {:error true})))
(fn []
(this-as this
(let [children (.. util/react
(toArray (.. this -props -children)))]
(when (not= 1 (count children))
(js/console.warn "Component error-boundary requires a single child component. Additional children are ignored."))
(if (gobj/get (.. this -state) "error")
(js/console.warn "An error occurred downstream (see errors above). The element subtree will not be rendered.")
(first children)))))})))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment