Skip to content

Instantly share code, notes, and snippets.

@pesterhazy
Created September 4, 2017 21:44
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pesterhazy/e6846be1b6712a9038537022d131ce46 to your computer and use it in GitHub Desktop.
Save pesterhazy/e6846be1b6712a9038537022d131ce46 to your computer and use it in GitHub Desktop.
Re-natal, reagent, react native error handling improved
;; Unfortunately, re-natal's stacktraces are not always great.
;;
;; The following two functions (downgrade-reagent-errors and set-error-handler)
;; give you better error messages in the Debug console (accessible in XCode
;; or using `react-native log-ios`).
;;
;; This should apply mutatis mutandis to Android.
(defonce !handler-set (atom false))
(defn downgrade-reagent-errors
"Downgrade reagent error to warning
Reagent uses console.error to notify the user that an exception occurs while
rendering. Unfortunately, react-native can only show one RedBox at a time and
discards all subseqeuent ones. This obscures the actual exception. By
downgrading the first screen to a warning, the second screen is actually shown
to the user."
[]
(when-not @!handler-set
(reset! !handler-set true)
(let [original-error (.-error js/console)]
(set! (.-error js/console)
(fn [& [head :as args]]
(if (and (string? head) (str/starts-with? head "Error rendering component"))
(apply (.-warn js/console) "Additional exception info:" args)
(apply original-error args)))))))
(defn format-error [e]
(if (instance? js/Error e)
{:name (.-name e) :message (.-message e) :stack (.-stack e)}
{:message (pr-str e)}))
(defn handle-error [e is-fatal]
(let [f (format-error e)]
(js/console.log (str "PRETTY PRINTED EXCEPTION"
"\n\n***\nNAME: "
(pr-str (:name f))
"\nMESSAGE: "
(:message f)
"\n\n"
(:stack f)
"\n\n***"))))
(defonce !error-handler-set? (atom false))
(defn set-error-handler []
(when-not @!error-handler-set?
(reset! !error-handler-set? true)
(let [orig-handler (some-> js/ErrorUtils .-getGlobalHandler (.call))]
(js/ErrorUtils.setGlobalHandler (fn [e isFatal]
(handle-error e isFatal)
(some-> orig-handler (.call nil e isFatal)))))))
(defn init []
(set-error-handler)
(downgrade-reagent-errors)
(.registerComponent app-registry
"Whatever"
#(r/reactify-component app-root)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment