Skip to content

Commit cc1e70a

Browse files
authored
fix #40337, no error info from serialized TaskFailedException (#40395)
1 parent 027bd4a commit cc1e70a

File tree

4 files changed

+18
-29
lines changed

4 files changed

+18
-29
lines changed

base/task.jl

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,12 @@ end
7979
function show_task_exception(io::IO, t::Task; indent = true)
8080
stack = catch_stack(t)
8181
b = IOBuffer()
82-
show_exception_stack(IOContext(b, io), stack)
82+
if isempty(stack)
83+
# exception stack buffer not available; probably a serialized task
84+
showerror(IOContext(b, io), t.result)
85+
else
86+
show_exception_stack(IOContext(b, io), stack)
87+
end
8388
str = String(take!(b))
8489
if indent
8590
str = replace(str, "\n" => "\n ")

stdlib/Distributed/src/clusterserialize.jl

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -102,19 +102,6 @@ function serialize(s::ClusterSerializer, t::Core.TypeName)
102102
nothing
103103
end
104104

105-
function serialize(s::ClusterSerializer, t::Task)
106-
serialize_cycle(s, t) && return
107-
if istaskstarted(t) && !istaskdone(t)
108-
error("cannot serialize a running Task")
109-
end
110-
writetag(s.io, TASK_TAG)
111-
serialize(s, t.code)
112-
serialize(s, t.storage)
113-
serialize(s, t._state)
114-
serialize(s, t.result)
115-
serialize(s, t._isexception)
116-
end
117-
118105
function serialize(s::ClusterSerializer, g::GlobalRef)
119106
# Record if required and then invoke the default GlobalRef serializer.
120107
sym = g.name
@@ -244,17 +231,6 @@ function deserialize(s::ClusterSerializer, t::Type{<:CapturedException})
244231
return CapturedException(capex, bt)
245232
end
246233

247-
function deserialize(s::ClusterSerializer, ::Type{Task})
248-
t = Task(nothing)
249-
deserialize_cycle(s, t)
250-
t.code = deserialize(s)
251-
t.storage = deserialize(s)
252-
t._state = deserialize(s)::UInt8
253-
t.result = deserialize(s)
254-
t._isexception = deserialize(s)
255-
t
256-
end
257-
258234
"""
259235
clear!(syms, pids=workers(); mod=Main)
260236

stdlib/Distributed/test/distributed_exec.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1675,7 +1675,7 @@ let e = @test_throws RemoteException pmap(1) do _
16751675
es = sprint(showerror, e.value)
16761676
@test contains(es, ":\nTaskFailedException\nStacktrace:\n")
16771677
@test contains(es, "\n\n nested task error:")
1678-
@test_broken contains(es, "\n\n nested task error: 42\n")
1678+
@test contains(es, "\n\n nested task error: 42\n")
16791679
end
16801680

16811681
# issue #27429, propagate relative `include` path to workers

stdlib/Serialization/src/Serialization.jl

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -458,11 +458,19 @@ function serialize(s::AbstractSerializer, t::Task)
458458
if istaskstarted(t) && !istaskdone(t)
459459
error("cannot serialize a running Task")
460460
end
461-
state = [t.code, t.storage, t.state, t.result, t._isexception]
462461
writetag(s.io, TASK_TAG)
463-
for fld in state
464-
serialize(s, fld)
462+
serialize(s, t.code)
463+
serialize(s, t.storage)
464+
serialize(s, t.state)
465+
if t._isexception && (stk = Base.catch_stack(t); !isempty(stk))
466+
# the exception stack field is hidden inside the task, so if there
467+
# is any information there make a CapturedException from it instead.
468+
# TODO: Handle full exception chain, not just the first one.
469+
serialize(s, CapturedException(stk[1][1], stk[1][2]))
470+
else
471+
serialize(s, t.result)
465472
end
473+
serialize(s, t._isexception)
466474
end
467475

468476
function serialize(s::AbstractSerializer, g::GlobalRef)

0 commit comments

Comments
 (0)