On 10/28/26 17:11, Daniel Sun wrote:
Hi Jochen, Matt,

Thanks for the example and the follow-up.

`defer` for `channel.close()` is still the right cleanup tool, and keeping the 
`Awaitable` from `async` so you can `await` it after the `for await` loop 
remains the cleanest way I see to surface the producer exception without 
inventing `async { } finally { }`.


my example was:

```groovy
def channel = AsyncChannel.create(2)

// send data to channel in another thread
async {
     for (int i = 1; i <= 3; i++) {
         someCall()
         channel.send(i * i)
     }
     channel.close()
}

// print all values send till the channel closed
for await (value in channel) {
     println value
}
```

and the problem was that if someCall() throws an exception we are left hanging. Yes, if we do not do a free async block this cannot happen, but then... why do we then allow them at all? Because it makes for short code.

The "Dungeon waves" example on https://groovy.apache.org/blog/groovy-async-await for example has the same basic problem. a free async, that will not be able to transport its exception.

I really think we need to find a solution to this.

bye Jochen

Reply via email to