Skip to content

Instantly share code, notes, and snippets.

@Lambeaux
Created October 11, 2021 20:02
Show Gist options
  • Save Lambeaux/6eb14e8c3e8af43c017a64c86722054a to your computer and use it in GitHub Desktop.
Save Lambeaux/6eb14e8c3e8af43c017a64c86722054a to your computer and use it in GitHub Desktop.
Toggle to keep NodeJS ClojureScript REPL from crashing on uncaught errors
(defn exception-handler [err]
(binding [*print-fn* *print-err-fn*]
(println "An error occurred that otherwise would have crashed the Node process:")
(println err)))
(defn handle-all []
(.on js/process "uncaughtException" exception-handler))
(defn handle-none []
(.removeListener js/process "uncaughtException" exception-handler))
@Lambeaux
Copy link
Author

The problem

To demonstrate the issue, run the following in a REPL backed by NodeJS and note the expected behavior:

(throw (ex-info "msg" {}))

The error is thrown and the REPL persists. It was able to catch the error.

(try (throw (ex-info "msg" {}))
     (catch :default e e))

The error is returned and the REPL persists. We were able to catch the error.

(try (go (throw (ex-info "msg" {})))
     (catch :default e e))

The channel is returned and the REPL dies. The error was thrown in an async context beyond the scope of both our try-catch and the REPL's try-catch.

Leveraging the snippet

Enable the crash protection like so:

(user/handle-all)
=> #object[process [object process]]

Try the problematic eval with protection enabled:

(try (go (throw (ex-info "msg" {})))
     (catch :default e e))
=> #object[cljs.core.async.impl.channels.ManyToManyChannel]
An error occurred that otherwise would have crashed the Node process:
#error {:message msg, :data {}}

When you're done, turn it off:

(user/handle-none)
=> #object[process [object process]]

Enjoy your REPL crashing again:

(try (go (throw (ex-info "msg" {})))
     (catch :default e e))
=> #object[cljs.core.async.impl.channels.ManyToManyChannel]

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