core.async with multiple catch blocks causing weird loop behaviour
Description
Environment
Attachments
Activity

Alex Miller February 13, 2017 at 8:29 PM
Marking as duplicate of ASYNC-169 which seems to address this issue as well.

Kevin Downey May 18, 2016 at 2:08 AM
the patch here no longer applies. http://dev.clojure.org/jira/browse/ASYNC-169 is a dupe of this, but it has a patch that applies

import January 26, 2016 at 4:46 PM
Comment made by: tgetgood
As it is, you need to catch Throwable
or nothing. Unhandled Throwables will cause this as well.
Will print an infinite stream of 1s.
It was a lot of fun figuring out why functions failing re conditions caused infinite loops.

import October 29, 2015 at 7:34 PM
Comment made by: kallen
This is even more troublesome when the exception is thrown from code that's not part of what the user wrote in the go block. You don't even need a loop for it to loop forever:
This was confusing as hell when we ran into it but catching Throwable instead does indeed work around the problem so that's what we've been doing. Was hoping the latest release of core.async would fix this.

Stuart Sierra June 18, 2015 at 8:52 PM
Possible workaround until this is fixed: Just have one catch
clause, catching all Throwable
. Then examine the type of the throwable object inside the catch
block to decide what to do.
Details
Details
Assignee
Reporter

Labels
Approval
Patch
Priority

I've been seeing this weird looping behavior with some go loops over the last few days. An exception is being thrown from a function within the loop and rather than logging and looping back around to a waiting take, the loop seems to just hop back to the line before the function call.
I've managed to boil it down to the following:
Now if you (>!! s :a), you'll see the throwable printed out and the loop go back to waiting on the s channel. However, (>!! d :a) and you'll get to enjoy an infinite stream of 'Double'. In actual fact you can remove the -loop from double and get the same result.
Not sure what's going on here at all. In the macro expanded version of double '(prn t)' doesn't appear at all (it does in single's expansion), so it looks like it's not surviving the move into the state machine and instead is routing back to (prn "Double") or the take isn't really completing somehow, leaving the :a on the chan.