core.async

Exceptions thrown inside go/thread blocks propagate up and out of ThreadPoolExcecutor

Details

  • Type: Enhancement Enhancement
  • Status: Open Open
  • Priority: Minor Minor
  • Resolution: Unresolved
  • Affects Version/s: None
  • Fix Version/s: None
  • Component/s: None
  • Labels:
  • Environment:
    core.async 0.1.267.0-0d7780-alpha on JDK 1.7

Description

If a go or thread blocks throws an exception, there is nothing in Clojure to catch and handle (or report) the exception. Instead, it propagates up to the ThreadExcecutor which invokes its NO-OP afterExecute() method and is re-thrown, ultimately being displayed on the System.err:

Exception in thread "async-dispatch-32" java.lang.IllegalStateException: Fall down, go boom!
at flashiz.resources.orders$index.invoke(orders.clj:26)
at clojure.lang.Var.invoke(Var.java:411)
at clojure.lang.AFn.applyToHelper(AFn.java:159)
at clojure.lang.Var.applyTo(Var.java:532)
at clojure.core$apply.invoke(core.clj:617)
at io.aviso.rook$rook_dispatcher.invoke(rook.clj:225)
at flashiz.async$wrap_sync_handler$fn__9005.invoke(async.clj:34)
at flashiz.resources$authorize_async_rook_middleware$fn_9356$fn9402$state_machine3245auto__9403$fn_9405.invoke(resources.clj:21)
at flashiz.resources$authorize_async_rook_middleware$fn_9356$fn9402$state_machine3245auto___9403.invoke(resources.clj:21)
at clojure.core.async.impl.ioc_macros$run_state_machine.invoke(ioc_macros.clj:945)
at clojure.core.async.impl.ioc_macros$run_state_machine_wrapped.invoke(ioc_macros.clj:949)
at clojure.core.async.impl.ioc_macros$take_BANG_$fn__3261.invoke(ioc_macros.clj:958)
at clojure.core.async.impl.channels.ManyToManyChannel$fn__2256.invoke(channels.clj:80)
at clojure.lang.AFn.run(AFn.java:24)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:724)

It would be nice if execution of the go/thread block was wrapped in an exception handler that delegated to a default function to report the exception. My goal is to be able to alter that function to report it more nicely and/or write it to a persistent log file.

Activity

Hide
Alex Miller added a comment -

Patches on ASYNC-76 have been applied and exceptions will now flow up to the top of the thread, where they can be caught by the standard Thread uncaught exception handler mechanism or ultimately by the default uncaught exception handler, which can be set for the application. There may still be further changes to support exception handling in thread/go.

Show
Alex Miller added a comment - Patches on ASYNC-76 have been applied and exceptions will now flow up to the top of the thread, where they can be caught by the standard Thread uncaught exception handler mechanism or ultimately by the default uncaught exception handler, which can be set for the application. There may still be further changes to support exception handling in thread/go.
Hide
Christian Weilbach added a comment -

I have hit this issue repeatedly as well, so I have implemented a comprehensive error-handling strategy as a library for `core.async`: https://github.com/replikativ/superv.async

It has certain limitations, e.g. there is no dynamic binding across async boundaries in cljs so the supervisor needs to be carried lexically, and I would prefer a default error-handling concept along the Erlang philosophy to have composable libraries built on `core.async`. Having said that, it works quite well and should provide you with the necessary means to install a logging supervisor.

Show
Christian Weilbach added a comment - I have hit this issue repeatedly as well, so I have implemented a comprehensive error-handling strategy as a library for `core.async`: https://github.com/replikativ/superv.async It has certain limitations, e.g. there is no dynamic binding across async boundaries in cljs so the supervisor needs to be carried lexically, and I would prefer a default error-handling concept along the Erlang philosophy to have composable libraries built on `core.async`. Having said that, it works quite well and should provide you with the necessary means to install a logging supervisor.
Kevin Downey made changes -
Field Original Value New Value
Labels exceptions try-catch

People

Vote (2)
Watch (2)

Dates

  • Created:
    Updated: