Created
September 4, 2017 21:44
-
-
Save pesterhazy/e6846be1b6712a9038537022d131ce46 to your computer and use it in GitHub Desktop.
Re-natal, reagent, react native error handling improved
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; 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