Dear all,
I got intrigued when I realized that exceptions can be silenced when iterating over a channel. However, the source code on GitHub indicates that exceptions should actually be rethrown. Then I realized that the file Channels.jl
on GitHub is actually different from its counterpart on my computer, though I should have the latest version of Julia.
Now to details. Here is my example along with version details:
_
_ _ _(_)_ | Documentation: https://docs.julialang.org
(_) | (_) (_) |
_ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help.
| | | | | | |/ _` | |
| | |_| | | | (_| | | Version 1.11.6 (2025-07-09)
_/ |\__'_|_|_|\__'_| | Official https://julialang.org/ release
|__/ |
julia> ch = Channel() do c
for x in 3:-1:-2
put!(c, sqrt(x))
end
end
Channel{Any}(0) (1 item available)
julia> for y in ch
println(y)
end
1.7320508075688772
1.4142135623730951
1.0
0.0
As one can see, no error is reported: when sqrt(-1)
is to be computed, the iteration ends and the error is silenced.
However, the definition of the method of iterate()
for channels in the file channels.jl
on GitHub reads:
function iterate(c::Channel, state=nothing)
if isopen(c) || isready(c)
try
return (take!(c), nothing)
catch e
if isa(e, InvalidStateException) && e.state === :closed
return nothing
else
rethrow()
end
end
else
# If the channel was closed with an exception, it needs to be thrown
if (@atomic :acquire c.state) === :closed
e = c.excp
if isa(e, InvalidStateException) && e.state === :closed
nothing
else
throw(e)
end
end
return nothing
end
end
This code does capture the error: when I defined a new function with that method, an error was reported. Then I realized that the file channels.jl
on my computer is different. The underlying method reads:
function iterate(c::Channel, state=nothing)
if isopen(c) || isready(c)
try
return (take!(c), nothing)
catch e
if isa(e, InvalidStateException) && e.state === :closed
return nothing
else
rethrow()
end
end
else
return nothing
end
end
This code silences possible exceptions, as displayed above.
However, I am wondering why the files are different. I have run juliaup update
. The date of the file channels.jl
on my computer is July 9, 2025, which matches the Julia version date. Is the file on GitHub (pointed by the official Julia documentation) actually a future version and is to appear on my computer after some time? Or is it, less likely, a dated version, so that exceptions are now no longer captured in this situation? This is important for me to know: will be in future safe simply to use Channel() do ... end
or should one create a task and a channel separately, bind the channel to the task, schedule the task and finally call fetch()
to capture possible exceptions?
Many thanks for the answer in advance!